function varargout = PreprocMEG(varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Reads MEG data into Fieldtrip and runs preprocessing. % % See: "help ft_read_header" for supported filetypes. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright (C) 2013-2014, Michael J. Cheung % % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more % details, see the documentation included with the software package. % % MEGPLS is free software: you can redistribute it and/or modify it under % the terms of the GNU General Public License version 2 as published by % the Free Software Foundation. This program is distributed in the hope % that it will be useful, but WITHOUT ANY WARRANTY; without even the % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % See the GNU General Public License for more details. % % You should have received a copy of the GNU General Public License along % with this program. If not, you can download the license here: % . % Last Modified by GUIDE v2.5 11-Jul-2014 17:49:28 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @PreprocMEG_OpeningFcn, ... 'gui_OutputFcn', @PreprocMEG_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT %=======================% % INITIALIZE GUIDE GUI: % %=======================% %--- Executes just before PreprocMEG is made visible. ---% %--------------------------------------------------------------% function PreprocMEG_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to PreprocMEG (see VARARGIN) % Choose default command line output for PreprocMEG handles.output = hObject; % Make sure toolbox paths are added: [PipelineDir, ~, ~] = fileparts(which('PreprocMEG.m')); addpath(genpath(PipelineDir)); rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from AnalysisID rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox CheckToolboxPaths(PipelineDir); if exist('ErrorLog_PreprocMEG.txt', 'file') delete('ErrorLog_PreprocMEG.txt'); end % Initializes variables being displayed: handles.paths.Rootpath = []; handles.paths.DataID = []; handles.name.DataID = []; handles.name.CurrentGroupID = []; handles.paths.CurrentGroupID = []; handles.name.SubjID = []; handles.gui.Status = []; handles.paths.DataFolder = []; handles.paths.DataFile = []; handles.paths.DataFullpath = []; handles.gui.DataFiletype = 'CTFds'; handles.gui.ReadHdrSuccess = []; handles.gui.DataContinuous = []; handles.gui.InputNumTrials = []; handles.gui.EventInfoExist = []; handles.gui.AllEventInfo = []; handles.name.CondID = []; handles.name.CurrentCondID = []; handles.paths.CurrentCondID = []; handles.gui.DetectedEvents = []; handles.epoch.TargetMarkers = []; handles.epoch.IncludedEvents = []; handles.epoch.ExcludedEvents = []; handles.time.Start = []; handles.time.End = []; handles.time.OverlapThresh = []; handles.time.IncEventStart = []; handles.time.IncEventEnd = []; handles.time.ExcEventStart = []; handles.time.ExcEventEnd = []; handles.FTcfg = []; handles.gui.LockPreprocSettings = 'off'; % Save handles: guidata(hObject, handles); % UIWAIT makes PreprocMEG wait for user response (see UIRESUME) % uiwait(handles.PreprocGUI); %** FOR NEUROMAG DATA, NEED TO SET BITRATE IN FT_PREPROCESSING: % - Ex: cfg.headerformat, cfg.dataformat, cfg.eventformat = 'ns_cnt32' % - Have options here to select bitrate. %--- Outputs from this function are returned to the command line. ---% %--------------------------------------------------------------------% function varargout = PreprocMEG_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; %===================================% % FUNCTIONS FOR SELECTING ROOTPATH: % %===================================% %--- Executes on button press in ButtonSetRootpath. ---% %------------------------------------------------------% function ButtonSetRootpath_Callback(hObject, eventdata, handles) if ~isempty(handles.name.DataID) prompt = {'WARNING:'; ''; 'Changing root directory will clear all current settings!'; ''; 'Do you wish to continue?'}; ChangeDir = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(ChangeDir, 'NO') return; end end % Select and set Rootpath: SelectedPath = uigetdir; if SelectedPath == 0 return % If user cancels end % Check if selected path has spaces (AFNI functions cannot read spaces): CheckSpaces = strfind(SelectedPath, ' '); if ~isempty(CheckSpaces) message = {'Error: Target directory selected contains spaces.'; 'AFNI functions cannot read folder & file paths with spaces.'; 'AFNI functions are required for file conversions later on.'}; msgbox(message, 'Error:') return; end handles.paths.Rootpath = SelectedPath; set(handles.TextboxRootpath, 'String', handles.paths.Rootpath); % Start Waitbox: WaitBox = StartWaitBox('SETTING ROOT DIRECTORY:'); % Reset DataID: handles.name.DataID = []; handles.paths.DataID = []; set(handles.TextboxDataID, 'String', 'Not Selected.'); % Reset GroupID: handles.name.CurrentGroupID = []; handles.paths.CurrentGroupID = []; set(handles.TextboxGroupID, 'String', 'Not Selected.'); % Reset settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles = ResetEpochSettings (handles); handles = ResetBaselineSettings (handles); handles = ResetGeneralFilterSettings (handles); handles = ResetBandstopFilterSettings (handles); handles = ResetDFTFilterSettings (handles); handles = ResetMedianFilterSettings (handles); handles = ResetDetrendSettings (handles); handles = ResetOtherAdvSettings (handles); % Unlock settings if locked: handles.gui.LockPreprocSettings = 'off'; set(handles.ButtonSaveLockSettings, 'Enable', 'on'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'on'); % Update settings & GUI panels (to enable/disable & unlock): % Note: Don't redetect CondID / Status yet since GroupID reset. handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Textbox to display selected Rootpath: ---% %---------------------------------------------% function TextboxRootpath_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxRootpath, 'String'); if ~isequal(EnteredText, handles.paths.Rootpath) set(handles.TextboxRootpath, 'String', handles.paths.Rootpath); msgbox('Note: Use button to change Rootpath.') end %===========================================% % FUNCTIONS FOR CREATING OR LOADING DATAID: % %===========================================% %--- Executes on button press in ButtonCreateDataID. ---% %-------------------------------------------------------% function ButtonCreateDataID_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end % Enter name of DataID: UserInput = inputdlg('Enter DataID name:', 'Create new DataID:'); UserInput = deblank(UserInput); UserInput = regexprep(UserInput, '\s+', '_'); if isempty(char(UserInput)) return; % If user cancels end PathInputID = [handles.paths.Rootpath,'/DataID_',UserInput{1}]; if exist(PathInputID, 'dir') msgbox('Error: Specified DataID already exists!', 'Error:') return; end % Set DataID & create folder: status = mkdir(PathInputID); if status == 1 % If mkdir successful handles.name.DataID = UserInput{1}; handles.paths.DataID = PathInputID; set(handles.TextboxDataID, 'String', handles.name.DataID); else msgbox('Error: Failed to create DataID folder.', 'Error:') return; end % Start Waitbox: WaitBox = StartWaitBox('CREATING DATA ID:'); % Reset GroupID: handles.name.CurrentGroupID = []; handles.paths.CurrentGroupID = []; set(handles.TextboxGroupID, 'String', 'None Selected'); % Reset settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles = ResetEpochSettings (handles); handles = ResetBaselineSettings (handles); handles = ResetGeneralFilterSettings (handles); handles = ResetBandstopFilterSettings (handles); handles = ResetDFTFilterSettings (handles); handles = ResetMedianFilterSettings (handles); handles = ResetDetrendSettings (handles); handles = ResetOtherAdvSettings (handles); % Unlock settings if locked: handles.gui.LockPreprocSettings = 'off'; set(handles.ButtonSaveLockSettings, 'Enable', 'on'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'on'); % Update settings & GUI panels (to enable/disable & unlock): % Note: Don't redetect CondID / Status yet since GroupID reset. handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Executes on button press in ButtonLoadDataID. ---% %-----------------------------------------------------% function ButtonLoadDataID_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end % Get DataID folders in current rootpath: DetectedFolders = dir([handles.paths.Rootpath,'/DataID_*']); DetectedFolders = [DetectedFolders; dir([handles.paths.Rootpath,'/DataID-ICAclean_*'])]; RemoveIndex = []; for d = 1:length(DetectedFolders) if DetectedFolders(d).isdir ~= 1 RemoveIndex = [RemoveIndex, d]; % Get unwanted indices end end DetectedFolders(RemoveIndex) = []; if isempty(DetectedFolders) msgbox('Error: No DataID folders detected inside root dir.', 'Error:'); return; end % List DataID folders for selection: DetectedFolders = {DetectedFolders.name}; SelectedIndex = listdlg('PromptString', 'Select DataID to load:',... 'ListSize', [300, 300], 'SelectionMode', 'single', 'ListString', DetectedFolders); if isempty(SelectedIndex) % If user cancels. return; end SelectedDataID = DetectedFolders{SelectedIndex}; % Check if DataID was ICA cleaned: if ~strcmp(SelectedDataID(1:7), 'DataID_') && strcmp(SelectedDataID(1:16), 'DataID-ICAclean_') message = {'IMPORTANT:'; ''; 'ICA-cleaned DataID folders cannot be directly loaded back into'; 'the MEG preprocessing module (PreprocMEG GUI).'; ''; 'If you wish to further preprocess files from DataID-ICAclean folders,'; 'create a new DataID and select the ICA cleaned files from there.'}; msgbox(message) return; end SelectedDataID(1:7) = []; % Remove "DataID_" prefix to get DataID tag. FullpathDataID = [handles.paths.Rootpath,'/DataID_',SelectedDataID]; % Set as current DataID: handles.name.DataID = SelectedDataID; handles.paths.DataID = FullpathDataID; set(handles.TextboxDataID, 'String', handles.name.DataID); % Start WaitBox: WaitBox = StartWaitBox('LOADING DATA ID:'); % Reset GroupID: handles.name.CurrentGroupID = []; handles.paths.CurrentGroupID = []; set(handles.TextboxGroupID, 'String', 'None Selected'); % Reset settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles = ResetEpochSettings (handles); handles = ResetBaselineSettings (handles); handles = ResetGeneralFilterSettings (handles); handles = ResetBandstopFilterSettings (handles); handles = ResetDFTFilterSettings (handles); handles = ResetMedianFilterSettings (handles); handles = ResetDetrendSettings (handles); handles = ResetOtherAdvSettings (handles); handles.gui.LockPreprocSettings = 'off'; set(handles.ButtonSaveLockSettings, 'Enable', 'on'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'on'); % Load PreprocSettings.mat for selected DataID: % Note: Don't load SubjID / CondID / InputData since GroupID reset. if exist([FullpathDataID,'/PreprocSettings.mat'], 'file') LoadedMat = load([FullpathDataID,'/PreprocSettings.mat']); handles = LoadEpochSettings (handles, LoadedMat); handles = LoadBaselineSettings (handles, LoadedMat); handles = LoadGeneralFilterSettings (handles, LoadedMat); handles = LoadBandstopFilterSettings (handles, LoadedMat); handles = LoadDFTFilterSettings (handles, LoadedMat); handles = LoadMedianFilterSettings (handles, LoadedMat); handles = LoadDetrendSettings (handles, LoadedMat); handles = LoadOtherAdvSettings (handles, LoadedMat); handles.gui.LockPreprocSettings = 'on'; set(handles.ButtonSaveLockSettings, 'Enable', 'off'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'off'); else message = {'WARNING:'; ''; 'PreprocSettings.mat was not found for selected DataID.'; 'Settings will need to be reconfigured from scratch.'; ''; 'If preprocessed data exists for this DataID, take care to match'; 'the same settings used before to avoid mismatch across datasets.'}; msgbox(message, 'WARNING:'); end % Update settings & GUI panels: % Note: Don't redetect CondID / Status yet since GroupID reset. handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Textbox to display current DataID: ---% %------------------------------------------% function TextboxDataID_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxDataID, 'String'); if ~isequal(EnteredText, handles.name.DataID) set(handles.TextboxDataID, 'String', handles.name.DataID); msgbox('Note: Use button to change DataID.') end %============================================% % FUNCTIONS FOR CREATING OR LOADING GROUPID: % %============================================% %--- Executes on button press in ButtonCreateGroupID. ---% %--------------------------------------------------------% function ButtonCreateGroupID_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end % Enter name of GroupID: UserInput = inputdlg('Enter GroupID name:', 'Create new GroupID:'); UserInput = deblank(UserInput); UserInput = regexprep(UserInput, '\s+', '_'); if isempty(char(UserInput)) return; % If user cancels end PathInputID = [handles.paths.DataID,'/GroupID_',UserInput{1}]; if exist(PathInputID, 'dir') msgbox('Error: Specified GroupID already exists for this DataID!', 'Error:') return; end % Set GroupID and create folder: status = mkdir(PathInputID); if status == 1 % If mkdir successful handles.name.CurrentGroupID = UserInput{1}; handles.paths.CurrentGroupID = PathInputID; set(handles.TextboxGroupID, 'String', handles.name.CurrentGroupID); else msgbox('Error: Failed to create GroupID folder.', 'Error:') return; end % Start Waitbox: WaitBox = StartWaitBox('CREATING GROUP ID:'); % Reset input settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); % Update settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Executes on button press in ButtonLoadGroupID. ---% %------------------------------------------------------% function ButtonLoadGroupID_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end % Acquire GroupID folders for current DataID: DetectedFolders = dir([handles.paths.DataID,'/GroupID_*']); RemoveIndex = []; for g = 1:length(DetectedFolders) if DetectedFolders(g).isdir ~= 1 RemoveIndex = [RemoveIndex, g]; % Get unwanted indices end end DetectedFolders(RemoveIndex) = []; if isempty(DetectedFolders) msgbox('Error: No GroupID folders were detected for current DataID.', 'Error:'); return; end % List detected GroupID folders and select desired GroupID: DetectedFolders = {DetectedFolders.name}; SelectedIndex = listdlg('PromptString', 'Select GroupID to load:',... 'ListSize', [300, 300], 'SelectionMode', 'single', 'ListString', DetectedFolders); if isempty(SelectedIndex) return; % If user cancels end SelectedGroupID = DetectedFolders{SelectedIndex}; SelectedGroupID(1:8) = []; % Remove "GroupID_" prefix to get GroupID. % Set as current GroupID: handles.name.CurrentGroupID = SelectedGroupID; handles.paths.CurrentGroupID = [handles.paths.DataID,'/GroupID_',SelectedGroupID]; set(handles.TextboxGroupID, 'String', handles.name.CurrentGroupID); % Start Waitbox: WaitBox = StartWaitBox('LOADING GROUP ID:'); % Reset input settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); % Load a PreprocInputMEG .mat for GroupID if available: CheckExist = dir([handles.paths.CurrentGroupID,'/PreprocInputMEG_*.mat']); if ~isempty(CheckExist) [matfile, matpath] = uigetfile([handles.paths.CurrentGroupID,... '/PreprocInputMEG_*.mat'], 'Select PreprocInputMEG .mat:', 'MultiSelect', 'off'); if matfile == 0 message = {'WARNING:'; ''; 'PreprocInputMEG .mat file was not selected.'; ''; 'Subject ID and selected dataset files will not be loaded.'; 'To select a PreprocInputMEG file, push the load button again.'}; msgbox(message, 'Warning:'); else LoadedMat = load([matpath,matfile]); handles = LoadSubjIDSettings (handles, LoadedMat); handles = LoadInputDataSettings (handles, LoadedMat); end else message = {'WARNING:'; ''; 'PreprocInputMEG .mat file(s) were not found in GroupID folder.'; 'SubjID and input datasets will need to be selected again.'}; msgbox(message, 'Warning:'); end % Redetect Events and CondID folders: handles = DetectDatasetEvents (handles); handles = DetectCondIDs (handles); % Update input settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Textbox to display current GroupID: ---% %-------------------------------------------% function TextboxGroupID_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxGroupID, 'String'); if ~isequal(EnteredText, handles.name.CurrentGroupID) set(handles.TextboxGroupID, 'String', handles.name.CurrentGroupID); msgbox('Note: Use button to change GroupID.') end %============================================% % FUNCTIONS FOR ADDING OR REMOVING SUBJECTS: % %============================================% %--- Executes on selection change in ListboxSubjID. ---% %------------------------------------------------------% function ListboxSubjID_Callback(hObject, eventdata, handles) SelectedIndex = get(handles.ListboxSubjID, 'Value'); set(handles.ListboxInputData, 'Value', SelectedIndex); set(handles.ListboxStatus, 'Value', SelectedIndex); %--- User enters subject to add into this textbox. ---% %-----------------------------------------------------% function TextboxSubjID_Callback(hObject, eventdata, handles) keypress = get(gcf,'CurrentCharacter'); if isequal(keypress, char(13)) ButtonAddSubjID_Callback(hObject, eventdata, handles); end %--- Executes on button press in ButtonAddSubjID. ---% %----------------------------------------------------% function ButtonAddSubjID_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load GroupID.', 'Warning:'); return; end % Reads and set SubjID: InputSubjID = get(handles.TextboxSubjID, 'String'); InputSubjID = deblank(InputSubjID); InputSubjID = regexprep(InputSubjID, '\s+', '_'); InputSubjID = cellstr(InputSubjID); if isempty(InputSubjID{1}) return; end if ~isempty(handles.name.SubjID) && ismember(InputSubjID{1}, handles.name.SubjID) return % If SubjID already added end handles.name.SubjID = [handles.name.SubjID; InputSubjID]; NewIndex = length(handles.name.SubjID); % Initialize data & status cells for new subject: handles.paths.DataFolder {NewIndex} = []; handles.paths.DataFile {NewIndex} = []; handles.paths.DataFullpath {NewIndex} = []; handles.gui.ReadHdrSuccess {NewIndex} = -1; handles.gui.DataContinuous {NewIndex} = -1; handles.gui.InputNumTrials {NewIndex} = -1; handles.gui.EventInfoExist {NewIndex} = -1; handles.gui.AllEventInfo {NewIndex} = []; handles.gui.Status {NewIndex} = []; % Update input settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: set(handles.ListboxSubjID, 'Value', length(handles.name.SubjID)); if ~isempty(handles.paths.DataFullpath) set(handles.ListboxInputData, 'Value', length(handles.name.SubjID)); end if ~isempty(handles.gui.Status) set(handles.ListboxStatus, 'Value', length(handles.name.SubjID)); end guidata(hObject, handles); %--- Executes on button press in ButtonRmvSubjID. ---% %----------------------------------------------------% function ButtonRmvSubjID_Callback(hObject, eventdata, handles) if isempty(handles.name.SubjID) return; end SelectedIndex = get(handles.ListboxSubjID, 'Value'); handles.name.SubjID(SelectedIndex) = []; % Remove data & status cells for removed subject: handles.paths.DataFolder (SelectedIndex) = []; handles.paths.DataFile (SelectedIndex) = []; handles.paths.DataFullpath (SelectedIndex) = []; handles.gui.ReadHdrSuccess (SelectedIndex) = []; handles.gui.DataContinuous (SelectedIndex) = []; handles.gui.InputNumTrials (SelectedIndex) = []; handles.gui.EventInfoExist (SelectedIndex) = []; handles.gui.AllEventInfo (SelectedIndex) = []; handles.gui.Status (SelectedIndex) = []; % Update input settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Updates SubjID settings & GUI panel: ---% %--------------------------------------------% function OutputHandles = UpdateSubjIDSettings(InputHandles) handles = InputHandles; % Update listbox: set(handles.ListboxSubjID, 'String', handles.name.SubjID); CurrentIndex = get(handles.ListboxSubjID, 'Value'); MaxSubjIndex = length(handles.name.SubjID); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxSubjIndex set(handles.ListboxSubjID, 'Value', MaxSubjIndex); set(handles.ListboxInputData, 'Value', MaxSubjIndex); set(handles.ListboxStatus, 'Value', MaxSubjIndex); end % Set output handles: OutputHandles = handles; %--- Load SubjID settings & GUI panel: ---% %-----------------------------------------% function OutputHandles = LoadSubjIDSettings(InputHandles, LoadedMat) handles = InputHandles; handles.name.SubjID = LoadedMat.name.SubjID; set(handles.ListboxSubjID, 'String', handles.name.SubjID); set(handles.ListboxSubjID, 'Value', 1); % Set output handles: OutputHandles = handles; %--- Reset SubjID settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetSubjIDSettings(InputHandles) handles = InputHandles; handles.name.SubjID = []; set(handles.ListboxSubjID, 'String', []); set(handles.ListboxSubjID, 'Value', 1); % Set output handles: OutputHandles = handles; %=========================================% % FUNCTIONS FOR ADDING/REMOVING DATASETS: % %=========================================% %--- Executes on selection change in DropdownDataFiletype. ---% %------------------------------------------------------------------% function DropdownDataFiletype_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end if ~isempty(handles.paths.DataFullpath) prompt = {'WARNING:'; ''; 'Changing filetype will clear selected datasets.'; ''; 'Do you wish to continue?'}; ChangeType = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(ChangeType, 'NO') return; end end % Clear and update input data: % Note: Don't ResetInputData since it will cancel dropdown selection. handles.paths.DataFolder = []; handles.paths.DataFile = []; handles.paths.DataFullpath = []; handles.gui.ReadHdrSuccess = []; handles.gui.DataContinuous = []; handles.gui.InputNumTrials = []; handles.gui.EventInfoExist = []; handles.gui.AllEventInfo = []; handles.gui.Status = []; for s = 1:length(handles.name.SubjID) % Reinitialize handles.paths.DataFolder{s} = []; handles.paths.DataFile{s} = []; handles.paths.DataFullpath{s} = []; handles.gui.ReadHdrSuccess{s} = -1; handles.gui.DataContinuous{s} = -1; handles.gui.InputNumTrials{s} = -1; handles.gui.EventInfoExist{s} = -1; handles.gui.AllEventInfo{s} = []; handles.gui.Status{s} = []; end handles = ResetEventSettings (handles); handles = ResetStatusSettings (handles); % Update settings & GUI panels: handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateOtherAdvSettings (handles); % Display warning for fieldtrip filetype: if strcmp(handles.gui.DataFiletype, 'Fieldtrip') message = {'WARNING:'; ''; 'Selecting for files that have already been preprocessed into FT format.'; 'It is up to user to keep track of what options have already been applied.'; 'If you are unsure, start with raw format to avoid complications.'}; msgbox(message, 'WARNING'); end % Save handles: guidata(hObject, handles); %--- Executes on selection change in ListboxInputData. ---% %---------------------------------------------------------% function ListboxInputData_Callback(hObject, eventdata, handles) SelectedIndex = get(handles.ListboxInputData, 'Value'); set(handles.ListboxSubjID, 'Value', SelectedIndex); set(handles.ListboxStatus, 'Value', SelectedIndex); %--- Executes on button press in CheckboxShowDataFullpath. ---% %-------------------------------------------------------------% function CheckboxShowDataFullpath_Callback(hObject, eventdata, handles) handles = UpdateInputDataSettings(handles); guidata(hObject, handles); %--- Executes on button press in ButtonAddInputData. ---% %-----------------------------------------------------% function ButtonAddInputData_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end if isempty(handles.name.SubjID) msgbox('Warning: Add SubjectID''s first.', 'Warning:'); return; end % Use "uipickfiles" (Douglas M. Schwarz, 2007) to select datasets: switch handles.gui.DataFiletype case 'CTFds' SelectedFiles = uipickfiles('FilterSpec', [handles.paths.Rootpath,'/*.ds'],... 'REfilter', '.ds$', 'REdirs', 0); case 'Other' SelectedFiles = uipickfiles('FilterSpec', handles.paths.Rootpath); case 'Fieldtrip' SelectedFiles = uipickfiles('FilterSpec', [handles.paths.Rootpath,'/*.mat'],... 'REfilter', '.mat$'); end if ~iscell(SelectedFiles) && SelectedFiles == 0 return; % If user cancels end % For each file, match to SubjID and perform checks: WrongFormat = {}; MatchFailed = {}; DataWaitbar = waitbar(0, ... 'Please wait. Scanning selected datasets:', 'Windowstyle', 'modal'); for f = 1:length(SelectedFiles) waitbar(f/length(SelectedFiles), DataWaitbar); [Folder, File, Ext] = fileparts(SelectedFiles{f}); % Check if selected file format is valid: if strcmp(handles.gui.DataFiletype, 'CTFds') && ~strcmp(Ext, '.ds') WrongFormat = [WrongFormat; SelectedFiles{f}]; continue; end if strcmp(handles.gui.DataFiletype, 'Fieldtrip') && ~strcmp(Ext, '.mat') WrongFormat = [WrongFormat; SelectedFiles{f}]; continue; end if strcmp(handles.gui.DataFiletype, 'Other') &&... (strcmp(Ext, '.ds') || strcmp(Ext, '.mat')) WrongFormat = [WrongFormat; SelectedFiles{f}]; continue; end % Check filename for SubjID match: % Find SubjID indices that matched. SubjMatch = regexp([File,Ext], handles.name.SubjID); SubjIndex = find(~cellfun(@isempty, SubjMatch)); if length(SubjIndex) > 1 % If multiple matches, try to isolate SubjID. SubjMatch = regexp([File,Ext], strcat(handles.name.SubjID, '_')); SubjIndex = find(~cellfun(@isempty, SubjMatch)); end if isempty(SubjIndex) || length(SubjIndex) > 1 % Files failing to match. MatchFailed = [MatchFailed; SelectedFiles{f}]; end % Adds dataset for matching SubjID: if length(SubjIndex) == 1 handles.paths.DataFolder {SubjIndex} = Folder; handles.paths.DataFile {SubjIndex} = [File,Ext]; handles.paths.DataFullpath {SubjIndex} = SelectedFiles{f}; handles.gui.Status {SubjIndex} = []; % Check dataset info: handles = CompileInputDataInfo(handles, SubjIndex); end end % SelectedFiles delete(DataWaitbar); % Display warning for files with errors: if ~isempty(WrongFormat) prompt = {'WARNING:'; ''; 'The following file(s) were not of the correct filetype:'; ''}; prompt = [prompt; WrongFormat]; msgbox(prompt, 'Warning:'); end if ~isempty(MatchFailed) prompt = {'WARNING:'; ''; 'The following file(s) could not be matched to a SubjID (Check naming).'; 'To manually add a file for SubjID, use the Force Select button.'; ''}; prompt = [prompt; MatchFailed]; msgbox(prompt, 'Warning:'); end % Update input settings & GUI panels: handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); % Detect status of newly selected input data: set(handles.CheckboxShowOutputStatus, 'Value', 0); handles = DetectStatus (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonForceAddData. ---% %-----------------------------------------------------% function ButtonForceAddData_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end if isempty(handles.name.SubjID) msgbox('Warning: Add SubjectID''s first.', 'Warning:'); return; end % Use "uipickfiles" (Douglas M. Schwarz, 2007) to select dataset: switch handles.gui.DataFiletype case 'CTFds' SelectedFile = uipickfiles('FilterSpec', [handles.paths.Rootpath,'/*.ds'],... 'NumFiles', 1, 'Output', 'char', 'REfilter', '.ds$', 'REdirs', 1); case 'Other' SelectedFile = uipickfiles('FilterSpec', handles.paths.Rootpath,... 'NumFiles', 1, 'Output', 'char'); case 'Fieldtrip' SelectedFile = uipickfiles('FilterSpec', [handles.paths.Rootpath,'/*.mat'],... 'NumFiles', 1, 'Output', 'char', 'REfilter', '.mat$'); end if SelectedFile == 0 return; % If user cancels end [Folder, File, Ext] = fileparts(SelectedFile); SelectedIndex = get(handles.ListboxSubjID, 'Value'); % Check if selected file format is valid: if strcmp(handles.gui.DataFiletype, 'CTFds') && ~strcmp(Ext, '.ds') msgbox('Error: Selected file should be CTF .ds format.', 'Error:') return; end if strcmp(handles.gui.DataFiletype, 'Fieldtrip') && ~strcmp(Ext, '.mat') msgbox('Error: Selected file should be Fieldtrip .mat.', 'Error:') return; end if strcmp(handles.gui.DataFiletype, 'Other') &&... (strcmp(Ext, '.ds') || strcmp(Ext, '.mat')) msgbox('Error: Selected file was incorrect filetype.', 'Error:') return; end % Add as input dataset for currently selected subject: handles.paths.DataFolder {SelectedIndex} = Folder; handles.paths.DataFile {SelectedIndex} = [File,Ext]; handles.paths.DataFullpath {SelectedIndex} = SelectedFile; handles.gui.Status {SelectedIndex} = []; % Check dataset info: handles = CompileInputDataInfo(handles, SelectedIndex); % Update input settings & GUI panels: handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); % Let user choose when to detect status here. handles = UpdateStatusSettings (handles); % Don't status detect for single selects. % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonRmvInputData. ---% %-----------------------------------------------------% function ButtonRmvInputData_Callback(hObject, eventdata, handles) if isempty(handles.paths.DataFile) return; end % Clear dataset for selected subject: SelectedIndex = get(handles.ListboxInputData, 'Value'); handles.paths.DataFolder {SelectedIndex} = []; handles.paths.DataFile {SelectedIndex} = []; handles.paths.DataFullpath {SelectedIndex} = []; handles.gui.ReadHdrSuccess {SelectedIndex} = -1; handles.gui.DataContinuous {SelectedIndex} = -1; handles.gui.InputNumTrials {SelectedIndex} = -1; handles.gui.EventInfoExist {SelectedIndex} = -1; handles.gui.AllEventInfo {SelectedIndex} = []; handles.gui.Status {SelectedIndex} = []; % Update input settings & GUI panels: handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Check and compile info for input datasets: ---% %--------------------------------------------------% function OutputHandles = CompileInputDataInfo(InputHandles, SubjIndex) handles = InputHandles; % Checks dataset hdr, events, and continuous / epoched: if ~strcmp(handles.gui.DataFiletype, 'Fieldtrip') try Hdr = []; Hdr = ft_read_header(handles.paths.DataFullpath{SubjIndex}); handles.gui.ReadHdrSuccess{SubjIndex} = 1; if Hdr.nTrials == 1 handles.gui.DataContinuous{SubjIndex} = 1; handles.gui.InputNumTrials{SubjIndex} = 1; else handles.gui.DataContinuous{SubjIndex} = 0; handles.gui.InputNumTrials{SubjIndex} = Hdr.nTrials; end catch handles.gui.ReadHdrSuccess{SubjIndex} = 0; handles.gui.DataContinuous{SubjIndex} = -1; % No Hdr handles.gui.InputNumTrials{SubjIndex} = -1; end Events = []; Events = ft_read_event(handles.paths.DataFullpath{SubjIndex}); if isempty(Events) handles.gui.EventInfoExist{SubjIndex} = 0; handles.gui.AllEventInfo {SubjIndex} = []; else handles.gui.EventInfoExist{SubjIndex} = 1; handles.gui.AllEventInfo {SubjIndex} = Events; end elseif strcmp(handles.gui.DataFiletype, 'Fieldtrip') LoadData = []; LoadData = LoadFTmat(handles.paths.DataFullpath{SubjIndex}, 'PreprocMEG'); if ~isempty(LoadData) && isfield(LoadData, 'hdr') NumTrials = length(LoadData.trial); handles.gui.ReadHdrSuccess{SubjIndex} = 1; if NumTrials == 1 handles.gui.DataContinuous{SubjIndex} = 1; handles.gui.InputNumTrials{SubjIndex} = 1; else handles.gui.DataContinuous{SubjIndex} = 0; handles.gui.InputNumTrials{SubjIndex} = NumTrials; end else handles.gui.ReadHdrSuccess{SubjIndex} = 0; handles.gui.DataContinuous{SubjIndex} = -1; % No Hdr handles.gui.InputNumTrials{SubjIndex} = -1; end if ~isempty(LoadData) && isfield(LoadData, 'AllEventInfo') handles.gui.EventInfoExist{SubjIndex} = 1; handles.gui.AllEventInfo {SubjIndex} = LoadData.AllEventInfo; else handles.gui.EventInfoExist{SubjIndex} = 0; handles.gui.AllEventInfo {SubjIndex} = []; end end % Set output handles: OutputHandles = handles; %--- Updates data settings & GUI panel: ---% %------------------------------------------% function OutputHandles = UpdateInputDataSettings(InputHandles) handles = InputHandles; % Make sure cells initialized: for s = 1:length(handles.name.SubjID) try handles.paths.DataFolder{s}; handles.paths.DataFile{s}; handles.paths.DataFullpath{s}; handles.gui.ReadHdrSuccess{s}; handles.gui.DataContinuous{s}; handles.gui.InputNumTrials{s}; handles.gui.EventInfoExist{s}; handles.gui.AllEventInfo{s}; catch handles.paths.DataFolder{s} = []; handles.paths.DataFile{s} = []; handles.paths.DataFullpath{s} = []; handles.gui.ReadHdrSuccess{s} = -1; handles.gui.DataContinuous{s} = -1; handles.gui.InputNumTrials{s} = -1; handles.gui.EventInfoExist{s} = -1; handles.gui.AllEventInfo{s} = []; end end % Update input data settings: DropdownOptions = get(handles.DropdownDataFiletype, 'String'); DataFiletype = DropdownOptions{get(handles.DropdownDataFiletype, 'Value')}; switch DataFiletype case 'CTF .ds' handles.gui.DataFiletype = 'CTFds'; case 'Other Format' handles.gui.DataFiletype = 'Other'; case 'Fieldtrip .mat' handles.gui.DataFiletype = 'Fieldtrip'; otherwise error('Unrecognized Option'); % error-check end % Update listbox: if get(handles.CheckboxShowDataFullpath, 'Value') == 1 set(handles.ListboxInputData, 'String', handles.paths.DataFullpath); else set(handles.ListboxInputData, 'String', handles.paths.DataFile); end % Enable/Disable GUI components: if strcmp(handles.gui.LockPreprocSettings, 'off') set(handles.DropdownDataFiletype, 'Enable', 'on'); else set(handles.DropdownDataFiletype, 'Enable', 'off'); end % Set output handles: OutputHandles = handles; %--- Load data settings & GUI panel: ---% %---------------------------------------% function OutputHandles = LoadInputDataSettings(InputHandles, LoadedMat) handles = InputHandles; % Load input data: handles.paths.DataFolder = LoadedMat.paths.DataFolder; handles.paths.DataFile = LoadedMat.paths.DataFile; handles.paths.DataFullpath = LoadedMat.paths.DataFullpath; handles.gui.DataFiletype = LoadedMat.gui.DataFiletype; % Ask user if they wish to refresh dataset info: prompt = {'RECHECK & RECOMPILE INFO FOR INPUT DATASETS BEING LOADED?'; ''; ['NOTE: Only required if the input datasets being loaded have been modified '... 'or replaced after their selection in previous sessions.']; ''; ['If the input datasets have not been altered since the time they were first '... 'loaded, this verification step can be skipped to save time.']}; RecheckData = questdlg(prompt, 'RECHECK DATA?', 'YES', 'NO', 'NO'); % Refresh or load dataset info: if strcmp(RecheckData, 'YES') % Recompile info CheckWaitbar = waitbar(0, ... 'Please wait. Checking datasets being loaded:', 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID) waitbar(s/length(handles.name.SubjID), CheckWaitbar); handles = CompileInputDataInfo(handles, s); end delete(CheckWaitbar); else handles.gui.ReadHdrSuccess = LoadedMat.gui.ReadHdrSuccess; handles.gui.DataContinuous = LoadedMat.gui.DataContinuous; handles.gui.InputNumTrials = LoadedMat.gui.InputNumTrials; handles.gui.EventInfoExist = LoadedMat.gui.EventInfoExist; handles.gui.AllEventInfo = LoadedMat.gui.AllEventInfo; end % Update GUI: set(handles.CheckboxShowDataFullpath, 'Value', 0); set(handles.ListboxInputData, 'String', handles.paths.DataFile); set(handles.ListboxInputData, 'Value', 1); switch handles.gui.DataFiletype case 'CTFds' DataFiletype = 'CTF .ds'; case 'Other' DataFiletype = 'Other Format'; case 'Fieldtrip' DataFiletype = 'Fieldtrip .mat'; end DropdownOptions = get(handles.DropdownDataFiletype, 'String'); DropdownValue = find(strcmp(DropdownOptions, DataFiletype)); set(handles.DropdownDataFiletype, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.') % error-check end % Set output handles: OutputHandles = handles; %--- Reset data settings & GUI panel: ---% %----------------------------------------% function OutputHandles = ResetInputDataSettings(InputHandles) handles = InputHandles; % Reset input data settings: handles.paths.DataFolder = []; handles.paths.DataFile = []; handles.paths.DataFullpath = []; handles.gui.ReadHdrSuccess = []; handles.gui.DataContinuous = []; handles.gui.InputNumTrials = []; handles.gui.EventInfoExist = []; handles.gui.AllEventInfo = []; for s = 1:length(handles.name.SubjID) handles.paths.DataFolder{s} = []; handles.paths.DataFile{s} = []; handles.paths.DataFullpath{s} = []; handles.gui.ReadHdrSuccess{s} = -1; handles.gui.DataContinuous{s} = -1; handles.gui.InputNumTrials{s} = -1; handles.gui.EventInfoExist{s} = -1; handles.gui.AllEventInfo{s} = []; end handles.gui.DataFiletype = 'CTFds'; % Reset GUI data panel: set(handles.CheckboxShowDataFullpath, 'Value', 0); set(handles.ListboxInputData, 'String', handles.paths.DataFile); set(handles.ListboxInputData, 'Value', 1); set(handles.DropdownDataFiletype, 'Value', 1); % Set output handles: OutputHandles = handles; %=========================================% % FUNCTIONS FOR SPECIFYING EPOCH-MARKERS: % %=========================================% %--- Listbox Functions: ---% %--------------------------% % --- Executes on selection change in ListboxDetectedEvents. function ListboxDetectedEvents_Callback(hObject, eventdata, handles) % --- Executes on selection change in ListboxTargetMarkers. function ListboxTargetMarkers_Callback(hObject, eventdata, handles) % --- Executes on selection change in ListboxIncludedEvents. function ListboxIncludedEvents_Callback(hObject, eventdata, handles) % --- Executes on selection change in ListboxExcludedEvents. function ListboxExcludedEvents_Callback(hObject, eventdata, handles) %--- Executes on button press in ButtonDetectEvents. ---% %-------------------------------------------------------% function ButtonDetectEvents_Callback(hObject, eventdata, handles) handles = DetectDatasetEvents (handles); handles = UpdateEventSettings (handles); handles = UpdateStatusSettings (handles); guidata(hObject, handles); %--- Executes on button press in ButtonAddMarker. ---% %----------------------------------------------------% function ButtonAddMarker_Callback(hObject, eventdata, handles) if isempty(handles.gui.DetectedEvents) return; end % Adds selected event as target marker: SelectedEvents = get(handles.ListboxDetectedEvents, 'Value'); for e = SelectedEvents EventValueString = handles.gui.DetectedEvents(e,3); if ~isempty(handles.epoch.TargetMarkers) && ... ismember(EventValueString, handles.epoch.TargetMarkers(:,3)) continue; % already added end handles.epoch.TargetMarkers = ... [handles.epoch.TargetMarkers; handles.gui.DetectedEvents(e,:)]; end % Save handles: handles = UpdateEventSettings(handles); guidata(hObject, handles); %--- Executes on button press in ButtonIncludeEvent. ---% %-------------------------------------------------------% function ButtonIncludeEvent_Callback(hObject, eventdata, handles) if isempty(handles.gui.DetectedEvents) return; end % Adds selected event to include (similar to "newDs IncludeEvent"): SelectedEvents = get(handles.ListboxDetectedEvents, 'Value'); for e = SelectedEvents EventValueString = handles.gui.DetectedEvents(e,3); if ~isempty(handles.epoch.TargetMarkers) && ... ismember(EventValueString, handles.epoch.TargetMarkers(:,3)) msgbox('Error: This event has already been set as target marker.') continue; end if ~isempty(handles.epoch.ExcludedEvents) && ... ismember(EventValueString, handles.epoch.ExcludedEvents(:,3)) msgbox('Error: Cannot set same event to be both included and excluded.') continue; end if ~isempty(handles.epoch.IncludedEvents) && ... ismember(EventValueString, handles.epoch.IncludedEvents(:,3)) continue; % already added end handles.epoch.IncludedEvents = ... [handles.epoch.IncludedEvents; handles.gui.DetectedEvents(e,:)]; end % Save handles: handles = UpdateEventSettings(handles); guidata(hObject, handles); %--- Executes on button press in ButtonExcludeEvent. ---% %-------------------------------------------------------% function ButtonExcludeEvent_Callback(hObject, eventdata, handles) if isempty(handles.gui.DetectedEvents) return; end % Adds selected event to include (similar to "newDs IncludeEvent"): SelectedEvents = get(handles.ListboxDetectedEvents, 'Value'); for e = SelectedEvents EventValueString = handles.gui.DetectedEvents(e,3); if ~isempty(handles.epoch.TargetMarkers) && ... ismember(EventValueString, handles.epoch.TargetMarkers(:,3)) msgbox('Error: This event has already been set as target marker.') continue; end if ~isempty(handles.epoch.IncludedEvents) && ... ismember(EventValueString, handles.epoch.IncludedEvents(:,3)) msgbox('Error: Cannot set same event to be both excluded and included.') continue; end if ~isempty(handles.epoch.ExcludedEvents) && ... ismember(EventValueString, handles.epoch.ExcludedEvents(:,3)) continue; % already added end handles.epoch.ExcludedEvents = ... [handles.epoch.ExcludedEvents; handles.gui.DetectedEvents(e,:)]; end % Save handles: handles = UpdateEventSettings(handles); guidata(hObject, handles); %--- Executes on button press in ButtonResetEvents. ---% %------------------------------------------------------% function ButtonResetEvents_Callback(hObject, eventdata, handles) % Reset selected events: handles.epoch.TargetMarkers = []; handles.epoch.IncludedEvents = []; handles.epoch.ExcludedEvents = []; % Save handles: handles = UpdateEventSettings(handles); guidata(hObject, handles); %--- Scans input datasets for detected events or markers: ---% %------------------------------------------------------------% function OutputHandles = DetectDatasetEvents(InputHandles) handles = InputHandles; % Scan available events (markers or triggers) for each selected dataset: % Compile event data into matrix: y1 = event-name, y2 = event-value, y3 = eventvaluestring. EventsWaitbar = waitbar(0,... 'Please wait. Compiling events from datasets:', 'Windowstyle', 'modal'); handles.gui.DetectedEvents = []; for s = 1:length(handles.name.SubjID) waitbar(s/length(handles.name.SubjID), EventsWaitbar); % Skip subject if dataset not selected or DNE: if isempty(handles.paths.DataFile{s}) continue; end if ~exist(handles.paths.DataFullpath{s}, 'file') StatusMsg = 'Error: Dataset could not be found. Reselect dataset.'; handles.gui.Status{s} = StatusMsg; continue; end % Get all events in dataset: AllEventInfo = handles.gui.AllEventInfo{s}; if isempty(AllEventInfo) && handles.gui.EventInfoExist{s} == 0 if ~strcmp(handles.gui.DataFiletype, 'Fieldtrip') StatusMsg = 'Error: Events could not be read from selected dataset.'; else StatusMsg = 'Error: AllEventInfo field not found in dataset.'; end handles.gui.Status{s} = StatusMsg; continue; end % For each event-type, acquire all unique trigger-values: UniqueEvents = unique({AllEventInfo.type}); for e = 1:length(UniqueEvents) EventType = UniqueEvents{e}; EventIndices = find(strcmp(EventType, {AllEventInfo.type})); % All indices for event. EventValues = unique([AllEventInfo(EventIndices).value]); % Unique values for event. % If event does not code for multiple triggers, simply add event: if isempty(EventValues) if isempty(handles.gui.DetectedEvents) ||... ~ismember(EventType, handles.gui.DetectedEvents(:,1)) NewIndex = size(handles.gui.DetectedEvents, 1) + 1; handles.gui.DetectedEvents{NewIndex,1} = EventType; handles.gui.DetectedEvents{NewIndex,2} = []; handles.gui.DetectedEvents{NewIndex,3} = EventType; end % If the event codes for multiple triggers, add each trigger: else for v = 1:length(EventValues) EventValueString = [EventType,': ',num2str(EventValues(v))]; if isempty(handles.gui.DetectedEvents) ||... ~ismember(EventValueString, handles.gui.DetectedEvents(:,3)) NewIndex = size(handles.gui.DetectedEvents, 1) + 1; handles.gui.DetectedEvents{NewIndex,1} = EventType; handles.gui.DetectedEvents{NewIndex,2} = EventValues(v); handles.gui.DetectedEvents{NewIndex,3} = EventValueString; end end end end % Events end % Subj delete(EventsWaitbar); % Sort list: if ~isempty(handles.gui.DetectedEvents) handles.gui.DetectedEvents = sortrows(handles.gui.DetectedEvents, 3); end % Save as output: OutputHandles = handles; %--- Update event settings & GUI panel: ---% %------------------------------------------% function OutputHandles = UpdateEventSettings(InputHandles) handles = InputHandles; DataContinuous = handles.gui.DataContinuous; EventInfoExist = handles.gui.EventInfoExist; % If raw datasets selected, check if they are continuous. % If epoched datasets have been selected, disable T=0 event selection. if ~strcmp(handles.gui.DataFiletype, 'Fieldtrip') if ~isempty(DataContinuous) && max(cellfun(@(x) x==0, DataContinuous)) == 1 % If non-continuous if strcmp(get(handles.ListboxTargetMarkers, 'Enable'), 'on') message = {'WARNING:'; ''; % Only warns if transitioning from enabled to disabled. 'Some of the selected datasets has already been epoched (not continuous).'; ''; 'Target T=0 Events for epoching can only be set for continuous datasets.'; 'To specify T=0 events, unselect the epoched datasets (see status box).'}; msgbox(message); end handles.epoch.TargetMarkers = []; set(handles.ListboxTargetMarkers, 'Enable', 'off'); set(handles.ButtonAddMarker, 'Enable', 'off'); %** LOCK PRESTIM, POSTSTIM AND OVERLAP AS WELL? But accomodate lock settings. % Note: if you do this, need to add UpdateTimeSettings to Select/ForceAdd/Remove data as well. else set(handles.ListboxTargetMarkers, 'Enable', 'on'); set(handles.ButtonAddMarker, 'Enable', 'on'); end set(handles.ListboxDetectedEvents, 'Enable', 'on'); set(handles.ListboxIncludedEvents, 'Enable', 'on'); set(handles.ListboxExcludedEvents, 'Enable', 'on'); set(handles.ButtonDetectEvents, 'Enable', 'on'); set(handles.ButtonIncludeEvent, 'Enable', 'on'); set(handles.ButtonExcludeEvent, 'Enable', 'on'); set(handles.ButtonResetEvents, 'Enable', 'on'); end % If FT .mat files selected, check if EventInfo exists. % If EventInfo exists, then check if continuous for T=0 event compatibility. if strcmp(handles.gui.DataFiletype, 'Fieldtrip') if ~isempty(EventInfoExist) && max(cellfun(@(x) x==0, EventInfoExist)) == 1 % If no exist if strcmp(get(handles.ListboxTargetMarkers, 'Enable'), 'on') message = {'WARNING:'; ''; % Only warns if transitioning from enabled to disabled. 'Some of the selected FT datasets do not contain the "AllEventInfo" field.'; 'As a result, events settings are unavailable and files will be read as is.'; ''; 'To specify events, unselect files missing the required field (see status).'; 'Note: The "AllEventInfo" field is created for raw files read by [MEG]PLS.'}; msgbox(message); end handles.epoch.TargetMarkers = []; handles.epoch.IncludedEvents = []; handles.epoch.ExcludedEvents = []; set(handles.ListboxDetectedEvents, 'Enable', 'off'); set(handles.ListboxTargetMarkers, 'Enable', 'off'); set(handles.ListboxIncludedEvents, 'Enable', 'off'); set(handles.ListboxExcludedEvents, 'Enable', 'off'); set(handles.ButtonDetectEvents, 'Enable', 'off'); set(handles.ButtonAddMarker, 'Enable', 'off'); set(handles.ButtonIncludeEvent, 'Enable', 'off'); set(handles.ButtonExcludeEvent, 'Enable', 'off'); set(handles.ButtonResetEvents, 'Enable', 'off'); else % if event info exists if ~isempty(DataContinuous) && max(cellfun(@(x) x==0, DataContinuous)) == 1 % if non-continuous if strcmp(get(handles.ListboxTargetMarkers, 'Enable'), 'on') message = {'WARNING:'; ''; % Only warns if transitioning from enabled to disabled. 'Some of the selected datasets have already been epoched.'; ''; 'Target T=0 Events for epoching can only be set for continuous datasets.'; 'To specify T=0 events, unselect the epoched datasets (see status box).'}; msgbox(message); end handles.epoch.TargetMarkers = []; set(handles.ListboxTargetMarkers, 'Enable', 'off'); set(handles.ButtonAddMarker, 'Enable', 'off'); else set(handles.ListboxTargetMarkers, 'Enable', 'on'); set(handles.ButtonAddMarker, 'Enable', 'on'); end set(handles.ListboxDetectedEvents, 'Enable', 'on'); set(handles.ListboxIncludedEvents, 'Enable', 'on'); set(handles.ListboxExcludedEvents, 'Enable', 'on'); set(handles.ButtonDetectEvents, 'Enable', 'on'); set(handles.ButtonIncludeEvent, 'Enable', 'on'); set(handles.ButtonExcludeEvent, 'Enable', 'on'); set(handles.ButtonResetEvents, 'Enable', 'on'); end end % Update detected events listbox: if isempty(handles.gui.DetectedEvents) set(handles.ListboxDetectedEvents, 'String', []); else set(handles.ListboxDetectedEvents, 'String', handles.gui.DetectedEvents(:,3)); end CurrentIndex = max(get(handles.ListboxDetectedEvents, 'Value')); MaxDetEvents = size(handles.gui.DetectedEvents, 1); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxDetEvents set(handles.ListboxDetectedEvents, 'Value', MaxDetEvents); end % Update target markers listbox: if isempty(handles.epoch.TargetMarkers) set(handles.ListboxTargetMarkers, 'String', []); else set(handles.ListboxTargetMarkers, 'String', handles.epoch.TargetMarkers(:,3)); end CurrentIndex = get(handles.ListboxTargetMarkers, 'Value'); MaxAddMarkers = size(handles.epoch.TargetMarkers, 1); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxAddMarkers set(handles.ListboxTargetMarkers, 'Value', MaxAddMarkers); end % Update include events listbox: if isempty(handles.epoch.IncludedEvents) set(handles.ListboxIncludedEvents, 'String', []); else set(handles.ListboxIncludedEvents, 'String', handles.epoch.IncludedEvents(:,3)); end CurrentIndex = get(handles.ListboxIncludedEvents, 'Value'); MaxIncEvents = size(handles.epoch.IncludedEvents, 1); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxIncEvents set(handles.ListboxIncludedEvents, 'Value', MaxIncEvents); end % Update exclude events listbox: if isempty(handles.epoch.ExcludedEvents) set(handles.ListboxExcludedEvents, 'String', []); else set(handles.ListboxExcludedEvents, 'String', handles.epoch.ExcludedEvents(:,3)); end CurrentIndex = get(handles.ListboxExcludedEvents, 'Value'); MaxExcEvents = size(handles.epoch.ExcludedEvents, 1); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxExcEvents set(handles.ListboxExcludedEvents, 'Value', MaxExcEvents); end % Set output handles: OutputHandles = handles; %--- Load event settings & GUI panel: ---% %----------------------------------------% function OutputHandles = LoadEventSettings(InputHandles, LoadedMat) handles = InputHandles; % Load event settings: handles.epoch.TargetMarkers = LoadedMat.epoch.TargetMarkers; handles.epoch.IncludedEvents = LoadedMat.epoch.IncludedEvents; handles.epoch.ExcludedEvents = LoadedMat.epoch.ExcludedEvents; % Load GUI panel: set(handles.ListboxTargetMarkers, 'String', handles.epoch.TargetMarkers); set(handles.ListboxIncludedEvents, 'String', handles.epoch.IncludedEvents); set(handles.ListboxExcludedEvents, 'String', handles.epoch.ExcludedEvents); % Set output handles: OutputHandles = handles; %--- Reset event settings & GUI panel: ---% %-----------------------------------------% function OutputHandles = ResetEventSettings(InputHandles) handles = InputHandles; % Reset event settings: handles.gui.DetectedEvents = []; handles.epoch.TargetMarkers = []; handles.epoch.IncludedEvents = []; handles.epoch.ExcludedEvents = []; % Reset GUI event panel: set(handles.ListboxDetectedEvents, 'String', []); set(handles.ListboxDetectedEvents, 'Value', 1); set(handles.ListboxTargetMarkers, 'String', []); set(handles.ListboxTargetMarkers, 'Value', 1); set(handles.ListboxIncludedEvents, 'String', []); set(handles.ListboxIncludedEvents, 'Value', 1); set(handles.ListboxExcludedEvents, 'String', []); set(handles.ListboxExcludedEvents, 'Value', 1); % Set output handles: OutputHandles = handles; %====================================================% % FUNCTIONS FOR VIEWING / SPECIFYING CONDITION ID'S: % %====================================================% %--- Executes on selection change in ListboxCondID. ---% %------------------------------------------------------% function ListboxCondID_Callback(hObject, eventdata, handles) % hObject handle to ListboxTargetMarkers (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) %--- Executes on button press in ButtonAddCondID. ---% %----------------------------------------------------% function ButtonAddCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end % Enter name of CondID: UserInput = inputdlg('Enter CondID name:', 'Create new CondID:'); UserInput = deblank(UserInput); UserInput = regexprep(UserInput, '\s+', '_'); if isempty(char(UserInput)) return; % If user cancels end PathInputID = [handles.paths.CurrentGroupID,'/',UserInput{1}]; if exist(PathInputID, 'dir') msgbox('Error: CondID already exists.', 'Error:') return; end % Create CondID folder: status = mkdir(PathInputID); if status == 0 msgbox('Error: Failed to create CondID folder.', 'Error:') return; end % Save handles: handles = DetectCondIDs (handles); handles = UpdateCondIDSettings (handles); guidata(hObject, handles); %--- Executes on button press in ButtonRmvCondID. ---% %----------------------------------------------------% function ButtonRmvCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.CondID) return; end prompt = {'WARNING:'; ''; 'If you remove this CondID, all preprocessed data inside the'; 'CondID folder will also be lost.'; ''; 'Do you wish to continue?'}; DeleteCond = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(DeleteCond, 'NO') return; end % Removes selected CondID and its respective folder: SelectedIndex = get(handles.ListboxCondID, 'Value'); SelectedCondID = handles.name.CondID{SelectedIndex}; status = rmdir([handles.paths.CurrentGroupID,'/',SelectedCondID], 's'); if status == 0 msgbox('Error: Failed to remove CondID folder.', 'Error:') return; end % If removed CondID is the CurrentCondID: if strcmp(SelectedCondID, handles.name.CurrentCondID) handles = ResetCondIDSettings(handles); handles = ResetStatusSettings(handles); end % Save handles: handles = DetectCondIDs (handles); handles = UpdateCondIDSettings (handles); guidata(hObject, handles); %--- Executes on button press in ButtonSetCurrentCondID. ---% %-----------------------------------------------------------% function ButtonSetCurrentCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.CondID) return; end % Set selected CondID in ListboxCondID as current condition: SelectedIndex = get(handles.ListboxCondID, 'Value'); SelectedCondID = handles.name.CondID{SelectedIndex}; if ~isempty(handles.name.CurrentCondID) &&... strcmp(SelectedCondID, handles.name.CurrentCondID) return; end handles.name.CurrentCondID = SelectedCondID; handles.paths.CurrentCondID = [handles.paths.CurrentGroupID,'/',SelectedCondID]; set(handles.TextboxCurrentCondID, 'String', handles.name.CurrentCondID); message = {['TARGET CONDITION-ID HAS BEEN SET TO: ',handles.name.CurrentCondID]; ''; 'Trials defined by current events will be epoched as this CondID.'; 'Preprocessing settings will be applied to files for this CondID.'}; msgbox(message, 'Update:') % Update input settings & GUI panels: handles = DetectCondIDs (handles); handles = UpdateCondIDSettings (handles); set(handles.CheckboxShowOutputStatus, 'Value', 1); handles = DetectStatus (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Textbox to display current target CondID: ---% %-------------------------------------------------% function TextboxCurrentCondID_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxCurrentCondID, 'String'); if ~isequal(EnteredText, handles.name.CurrentCondID) set(handles.TextboxCurrentCondID, 'String', handles.name.CurrentCondID); msgbox('Note: Use button to change current target CondID.') end %--- Detect available CondID folders CurrentGroupID: ---% %-------------------------------------------------------% function OutputHandles = DetectCondIDs(InputHandles) handles = InputHandles; % Check if DataID has been selected & if MEGdata folder exists: if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end % Detect CondID folders for selected DataID & GroupID: DetectedCondIDs = dir([handles.paths.CurrentGroupID,'/*']); RemoveIndex = []; for c = 1:length(DetectedCondIDs) if DetectedCondIDs(c).isdir ~= 1 || ismember(DetectedCondIDs(c).name, {'.', '..'}) RemoveIndex = [RemoveIndex, c]; % Get unwanted indices end end DetectedCondIDs(RemoveIndex) = []; DetectedCondIDs = {DetectedCondIDs.name}; handles.name.CondID = DetectedCondIDs; % Save as output: OutputHandles = handles; %--- Update CondID settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = UpdateCondIDSettings(InputHandles) handles = InputHandles; % Update listbox: set(handles.ListboxCondID, 'String', handles.name.CondID); CurrentIndex = get(handles.ListboxCondID, 'Value'); MaxCondIndex = length(handles.name.CondID); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxCondIndex set(handles.ListboxCondID, 'Value', MaxCondIndex); end set(handles.TextboxCurrentCondID, 'String', handles.name.CurrentCondID); % Set output handles: OutputHandles = handles; %--- Load CondID settings & GUI panel: ---% %-----------------------------------------% function OutputHandles = LoadCondIDSettings(InputHandles, LoadedMat) handles = InputHandles; % Load CondID settings: % Note: For handles.name.CondID, just redetect conds. handles.name.CurrentCondID = LoadedMat.name.CurrentCondID; handles.paths.CurrentCondID = [handles.paths.CurrentGroupID,'/',handles.name.CurrentCondID]; % Load GUI panel: set(handles.TextboxCurrentCondID, 'String', handles.name.CurrentCondID); % Set output handles: OutputHandles = handles; %--- Reset CondID settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetCondIDSettings(InputHandles) handles = InputHandles; % Reset CondID settings: handles.name.CondID = []; handles.name.CurrentCondID = []; handles.paths.CurrentCondID = []; % Reset GUI CondID panel: set(handles.ListboxCondID, 'String', []); set(handles.ListboxCondID, 'Value', 1); set(handles.TextboxCurrentCondID, 'String', []); % Set output handles: OutputHandles = handles; %===============================% % FUNCTIONS FOR STATUS UPDATES: % %===============================% %--- Executes on selection change in ListboxStatus. ---% %------------------------------------------------------% function ListboxStatus_Callback(hObject, eventdata, handles) SelectedIndex = get(handles.ListboxStatus, 'Value'); set(handles.ListboxSubjID, 'Value', SelectedIndex); set(handles.ListboxInputData, 'Value', SelectedIndex); %--- Executes on button press in CheckboxShowOutputStatus. ---% %-------------------------------------------------------------% function CheckboxShowOutputStatus_Callback(hObject, eventdata, handles) handles = DetectStatus (handles); handles = UpdateStatusSettings (handles); guidata(hObject, handles); %--- Executes on button press in ButtonUpdateStatus. ---% %-------------------------------------------------------% function ButtonUpdateStatus_Callback(hObject, eventdata, handles) handles = DetectStatus (handles); handles = UpdateStatusSettings (handles); guidata(hObject, handles); %--- Function to acquire status of data: ---% %-------------------------------------------% function OutputHandles = DetectStatus(InputHandles) handles = InputHandles; StatusWaitbar = waitbar(0,... 'Please wait. Scanning Subject Datasets:', 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID) waitbar(s/length(handles.name.SubjID), StatusWaitbar); StatusMsg = []; % Status will be built upon if ~isempty(handles.name.CurrentCondID) EpochedFile = [handles.paths.CurrentCondID,'/',handles.name.SubjID{s},'_PreprocMEG.mat']; else EpochedFile = []; end if ~exist(EpochedFile, 'file') || get(handles.CheckboxShowOutputStatus, 'Value') == 0 if isempty(handles.paths.DataFullpath{s}) % If data not selected. handles.gui.Status{s} = 'Warning: Select dataset for this subject.'; continue; end if exist(handles.paths.DataFullpath{s}, 'file') % If input data found StatusMsg = 'Input dataset found'; else handles.gui.Status{s} = 'Error: Dataset could not be found. Reselect file.'; continue; end if handles.gui.ReadHdrSuccess{s} == 0 StatusMsg = [StatusMsg,'. Failed to read Hdr.']; elseif handles.gui.ReadHdrSuccess{s} == 1 switch handles.gui.DataContinuous{s} case 1 StatusMsg = [StatusMsg,' (Continuous)']; case 0 NumTrials = [num2str(handles.gui.InputNumTrials{s}),' trials']; StatusMsg = [StatusMsg,' (Epoched: ',NumTrials,')']; end switch handles.gui.EventInfoExist{s} case 1 StatusMsg = [StatusMsg,'. Event info found.']; case 0 StatusMsg = [StatusMsg,'. Event info missing.']; end end elseif get(handles.CheckboxShowOutputStatus, 'Value') == 1 EpochedData = LoadFTmat(EpochedFile, 'PreprocMEG'); if isempty(EpochedData) StatusMsg = 'Error: Output file found, but contains errors. See ErrorLog.'; else NumTrials = size(EpochedData.trial, 2); StatusMsg = ['Output file detected: ',num2str(NumTrials),' trials.']; end end handles.gui.Status{s} = StatusMsg; end % Subj delete(StatusWaitbar); % Save as output: OutputHandles = handles; % Remove ErrorLog if empty: if exist([pwd,'/ErrorLog_PreprocMEG.txt'], 'file') LogCheck = dir('ErrorLog_PreprocMEG.txt'); if LogCheck.bytes == 0 delete('ErrorLog_PreprocMEG.txt'); end end %--- Update status settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = UpdateStatusSettings(InputHandles) handles = InputHandles; % Make sure cells initialized: for s = 1:length(handles.name.SubjID) try handles.gui.Status{s}; catch handles.gui.Status{s} = []; end end % Update listbox: set(handles.ListboxStatus, 'String', handles.gui.Status); % Set output handles: OutputHandles = handles; %--- Reset status settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetStatusSettings(InputHandles) handles = InputHandles; % Reset status settings: handles.gui.Status = []; for s = 1:length(handles.name.SubjID) handles.gui.Status{s} = []; end % Reset GUI status panel: set(handles.ListboxStatus, 'String', []); set(handles.ListboxStatus, 'Value', 1); % Set output handles: OutputHandles = handles; %===============================================% % FUNCTIONS FOR SAVING & LOADING PREPROC INPUT: % %===============================================% %--- Executes on button press in ButtonSaveInput. ---% %----------------------------------------------------% function ButtonSaveInput_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Group has not been selected yet.', 'Warning:'); return; end if isempty(handles.name.CurrentCondID) msgbox('Warning: Current CondID has not been selected yet.', 'Warning:'); return; end if isempty(handles.name.SubjID) || isempty(handles.paths.DataFullpath) msgbox('Warning: Subjects & Datasets have not been selected.', 'Warning:'); return; end % Make sure rootpath & DataID don't have spaces (will cause issues for AFNI later): CheckSpaces1 = strfind(handles.paths.Rootpath, ' '); CheckSpaces2 = strfind(handles.paths.DataID, ' '); if ~isempty(CheckSpaces1) || ~isempty(CheckSpaces2) message = {'Error: Target directory or DataID contains spaces.'; 'AFNI functions cannot read folder & file paths with spaces.'; 'AFNI functions are required for file conversions later on.'}; msgbox(message, 'Error:') return; end % Check save path: SavePath = [handles.paths.CurrentGroupID,... '/PreprocInputMEG_',handles.name.CurrentCondID,'.mat']; if exist(SavePath, 'file') prompt = {'WARNING:'; ''; 'PreprocInputMEG .mat file already exists for this CondID.'; 'Are you sure you wish to OVERWRITE the existing file?'}; OverwriteMat = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(OverwriteMat, 'NO') return; else delete(SavePath); end end % Save input parameters for current GroupID and CondID: name.DataID = handles.name.DataID; name.SubjID = handles.name.SubjID; name.CurrentGroupID = handles.name.CurrentGroupID; name.CurrentCondID = handles.name.CurrentCondID; paths = handles.paths; % Rmv GUI only paths that aren't in load fcns. paths = rmfield(paths, 'Rootpath'); % - These paths auto-adapt if folders moved. paths = rmfield(paths, 'DataID'); paths = rmfield(paths, 'CurrentGroupID'); paths = rmfield(paths, 'CurrentCondID'); epoch.TargetMarkers = handles.epoch.TargetMarkers; epoch.IncludedEvents = handles.epoch.IncludedEvents; epoch.ExcludedEvents = handles.epoch.ExcludedEvents; gui = handles.gui; % Rmv GUI only parameters that aren't loaded. gui = rmfield(gui, 'Status'); % - These auto-adapt once loaded. gui = rmfield(gui, 'DetectedEvents'); gui = rmfield(gui, 'LockPreprocSettings'); CheckSavePath(SavePath, 'PreprocMEG'); save(SavePath, 'name', 'paths', 'epoch', 'gui'); % Feedback: if exist(SavePath, 'file') msgbox('Current input parameters successfully saved.', 'Success') else msgbox('Error: Failed to save input parameters.', 'Error:') end %--- Executes on button press in ButtonLoadInput. ---% %----------------------------------------------------% function ButtonLoadInput_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load GroupID.', 'Warning:'); return; end % Select and load PreprocInputMEG .mat: [matfile, matpath] = uigetfile([handles.paths.CurrentGroupID,... '/PreprocInputMEG_*.mat'], 'Select PreprocInputMEG .mat:', 'MultiSelect', 'off'); if matfile == 0 msgbox('Note: Load cancelled. File was not selected.', 'Note:'); return; end % Start Waitbox: WaitBox = StartWaitBox('LOADING INPUT SETTINGS:'); % Reset input settings & GUI panels: handles = ResetSubjIDSettings (handles); handles = ResetInputDataSettings (handles); handles = ResetEventSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); % Load input settings & GUI panels: LoadedMat = load([matpath,matfile]); handles = LoadSubjIDSettings (handles, LoadedMat); handles = LoadInputDataSettings (handles, LoadedMat); handles = LoadEventSettings (handles, LoadedMat); handles = LoadCondIDSettings (handles, LoadedMat); % Redetect CondID folders & dataset events: handles = DetectCondIDs (handles); handles = DetectDatasetEvents (handles); % Update input settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %==============================% % FUNCTIONS FOR TIME SETTINGS: % %==============================% %--- User enters prestimulus time here: ---% %------------------------------------------% function TextboxPrestimTime_Callback(hObject, eventdata, handles) PrestimTime = str2num(get(handles.TextboxPrestimTime, 'String')); PoststimTime = str2num(get(handles.TextboxPoststimTime, 'String')); if isempty(PrestimTime) msgbox('Error: Pre-stimulus time must be specified.', 'Error:'); return; end if ~isempty(PoststimTime) && (PrestimTime < 0 && (PrestimTime*-1 > PoststimTime)) msgbox('Error: Epoch start time cannot exceed end time.', 'Error:'); set(handles.TextboxPrestimTime, 'String', []); return; end if PrestimTime < 0 prompt = {'Warning:'; ''; ['You have input a negative amount of prestimulus time: ',num2str(PrestimTime)]; ['This means your epoch will currently start at: ',num2str(abs(PrestimTime)),'s']}; msgbox(prompt, 'Warning:') end % Adjust inc. & exc. event search times and baseline: EpochStartTime = PrestimTime * -1; EpochEndTime = PoststimTime; set(handles.TextboxIncEventStartTime, 'String', num2str(EpochStartTime, '%1.3f')); set(handles.TextboxExcEventStartTime, 'String', num2str(EpochStartTime, '%1.3f')); set(handles.TextboxBaselineStart, 'String', num2str(EpochStartTime, '%1.3f')); % Adjust default overlap threshold: if EpochStartTime > 0 set(handles.TextboxOverlapThreshold, 'String', num2str(0, '%1.3f')); else set(handles.TextboxOverlapThreshold, 'String', num2str(abs(EpochStartTime), '%1.3f')); end % Adjust padding length: EpochLength = EpochEndTime - EpochStartTime; if EpochLength < 5 % If less than 5s, pad to 10s (for sharp DFT filter). set(handles.TextboxPaddingLength, 'String', num2str(10, '%1.3f')); else PadToLength = EpochLength + 5; % Otherwise, use 5s of padding. set(handles.TextboxPaddingLength, 'String', num2str(PadToLength, '%1.3f')); end % Save handles: handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); guidata(hObject, handles); %--- User enters poststimulus time here: ---% %-------------------------------------------% function TextboxPoststimTime_Callback(hObject, eventdata, handles) PoststimTime = str2num(get(handles.TextboxPoststimTime, 'String')); PrestimTime = str2num(get(handles.TextboxPrestimTime, 'String')); if isempty(PoststimTime) msgbox('Error: Post-stimulus time must be specified.', 'Error:'); return; end if ~isempty(PrestimTime) && (PrestimTime < 0 && (PrestimTime*-1 > PoststimTime)) msgbox('Error: Epoch end time cannot be less than start time.', 'Error:'); set(handles.TextboxPoststimTime, 'String', []); return; end % Adjust inc. & exc. event search times: EpochStartTime = PrestimTime * -1; EpochEndTime = PoststimTime; set(handles.TextboxIncEventEndTime, 'String', num2str(EpochEndTime, '%1.3f')); set(handles.TextboxExcEventEndTime, 'String', num2str(EpochEndTime, '%1.3f')); % Adjust padding length: EpochLength = EpochEndTime - EpochStartTime; if EpochLength < 5 % If less than 5s, pad to 10s (for sharp DFT filter). set(handles.TextboxPaddingLength, 'String', num2str(10, '%1.3f')); else PadToLength = EpochLength + 5; % Otherwise, use 5s of padding. set(handles.TextboxPaddingLength, 'String', num2str(PadToLength, '%1.3f')); end % Save handles: handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters overlap threshold length here: ---% %--------------------------------------------------% function TextboxOverlapThreshold_Callback(hObject, eventdata, handles) OverlapThreshold = str2num(get(handles.TextboxOverlapThreshold, 'String')); if isempty(OverlapThreshold) msgbox('Error: Overlap threshold must be specified.', 'Error:') set(handles.TextboxOverlapThreshold, 'String', num2str(0, '%1.3f')); return; end handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters start search time for include events: ---% %---------------------------------------------------------% function TextboxIncEventStartTime_Callback(hObject, eventdata, handles) if isempty(handles.time.Start) || isempty(handles.time.End) msgbox('Warning: Specify prestim & poststim time first.', 'Warning:') return; end StartTime = str2num(get(handles.TextboxIncEventStartTime, 'String')); EndTime = str2num(get(handles.TextboxIncEventEndTime, 'String')); if isempty(StartTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify start search time for included events.', 'Error:') set(handles.TextboxIncEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end if (StartTime < handles.time.Start) || (StartTime > handles.time.End) msgbox('Error: Specified time is outside bounds of epoch time.', 'Error:') set(handles.TextboxIncEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end if StartTime > EndTime msgbox('Error: Start time cannot be greater than end time.', 'Error:') set(handles.TextboxIncEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters end search time for include events: ---% %-------------------------------------------------------% function TextboxIncEventEndTime_Callback(hObject, eventdata, handles) if isempty(handles.time.Start) || isempty(handles.time.End) msgbox('Warning: Specify prestim & poststim time first.', 'Warning:') return; end EndTime = str2num(get(handles.TextboxIncEventEndTime, 'String')); StartTime = str2num(get(handles.TextboxIncEventStartTime, 'String')); if isempty(EndTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify end search time for included events.', 'Error:') set(handles.TextboxIncEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end if (EndTime > handles.time.End) || (EndTime < handles.time.Start) msgbox('Error: Specified time is outside bounds of epoch time.', 'Error:') set(handles.TextboxIncEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end if EndTime < StartTime msgbox('Error: End time cannot be greater than start time.', 'Error:') set(handles.TextboxIncEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters start search time for exclude events: ---% %---------------------------------------------------------% function TextboxExcEventStartTime_Callback(hObject, eventdata, handles) if isempty(handles.time.Start) || isempty(handles.time.End) msgbox('Warning: Specify prestim & poststim time first.', 'Warning:') return; end StartTime = str2num(get(handles.TextboxExcEventStartTime, 'String')); EndTime = str2num(get(handles.TextboxExcEventEndTime, 'String')); if isempty(StartTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify start search time for excluded events.', 'Error:') set(handles.TextboxExcEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end if (StartTime < handles.time.Start) || (StartTime > handles.time.End) msgbox('Error: Specified time is outside bounds of epoch time.', 'Error:') set(handles.TextboxExcEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end if StartTime > EndTime msgbox('Error: Start time cannot be greater than end time.', 'Error:') set(handles.TextboxExcEventStartTime, 'String', num2str(handles.time.Start, '%1.3f')); return; end handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters end search time for exclude events: ---% %-------------------------------------------------------% function TextboxExcEventEndTime_Callback(hObject, eventdata, handles) if isempty(handles.time.Start) || isempty(handles.time.End) msgbox('Warning: Specify prestim & poststim time first.', 'Warning:') return; end EndTime = str2num(get(handles.TextboxExcEventEndTime, 'String')); StartTime = str2num(get(handles.TextboxExcEventStartTime, 'String')); if isempty(EndTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify end search time for excluded events.', 'Error:') set(handles.TextboxExcEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end if (EndTime > handles.time.End) || (EndTime < handles.time.Start) msgbox('Error: Specified time is outside bounds of epoch time.', 'Error:') set(handles.TextboxExcEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end if EndTime < StartTime msgbox('Error: End time cannot be greater than start time.', 'Error:') set(handles.TextboxExcEventEndTime, 'String', num2str(handles.time.End, '%1.3f')); return; end handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- User enters filter padding length here: ---% %-----------------------------------------------% function TextboxPaddingLength_Callback(hObject, eventdata, handles) FilterPadding = str2num(get(handles.TextboxPaddingLength, 'String')); if isempty(FilterPadding) set(handles.TextboxPaddingLength, 'String', num2str(0)); end message = {'WARNING:'; ''; 'Data will be padded TO this specified length (not WITH this length)!'; 'This is due to the way FieldTrip reads and applies filter padding.'; ''; 'Ex: If your epoch length is 2s, and 10s of padding is specified,'; ' then 8s of padding will be added (data will be padded TO 10s).'; ''; 'As a result, if your epoch length is larger than the time specified'; 'here for filter padding, then no padding will be added.'}; msgbox(message, 'WARNING:'); %** ADD AUTOADJUST AS WELL handles = UpdateEpochSettings(handles); guidata(hObject, handles); %--- Updates epoch & pad-length settings: ---% %--------------------------------------------% function OutputHandles = UpdateEpochSettings(InputHandles) handles = InputHandles; time = handles.time; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: FTcfg.DefineTrial.trialfun = 'ft_trialfun_general'; FTcfg.DefineTrial.trialdef.prestim = str2num(get(handles.TextboxPrestimTime, 'String')); FTcfg.DefineTrial.trialdef.poststim = str2num(get(handles.TextboxPoststimTime, 'String')); FTcfg.Preproc.padding = str2num(get(handles.TextboxPaddingLength, 'String')); time.Start = str2num(get(handles.TextboxPrestimTime, 'String')) * -1; time.End = str2num(get(handles.TextboxPoststimTime, 'String')); time.OverlapThresh = str2num(get(handles.TextboxOverlapThreshold, 'String')); time.IncEventStart = str2num(get(handles.TextboxIncEventStartTime, 'String')); time.IncEventEnd = str2num(get(handles.TextboxIncEventEndTime, 'String')); time.ExcEventStart = str2num(get(handles.TextboxExcEventStartTime, 'String')); time.ExcEventEnd = str2num(get(handles.TextboxExcEventEndTime, 'String')); % Enable/Disable GUI components: set(findall(handles.PanelEpochTime, '-property', 'Enable'), 'Enable', 'on'); set(findall(handles.PanelFilterPadding, '-property', 'Enable'), 'Enable', 'on'); set(handles.TextboxPaddingLength, 'Enable', 'on'); set(handles.TextPaddingLength, 'Enable', 'on'); set(handles.TextboxIncEventStartTime, 'Enable', 'on'); set(handles.TextboxIncEventEndTime, 'Enable', 'on'); set(handles.TextIncEventStartTime, 'Enable', 'on'); set(handles.TextIncEventEndTime, 'Enable', 'on'); set(handles.TextboxExcEventStartTime, 'Enable', 'on'); set(handles.TextboxExcEventEndTime, 'Enable', 'on'); set(handles.TextExcEventStartTime, 'Enable', 'on'); set(handles.TextExcEventEndTime, 'Enable', 'on'); % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelEpochTime, '-property', 'Enable'), 'Enable', 'off'); set(handles.TextboxOverlapThreshold, 'Enable', 'on'); % Keep thresh & inc/exc time on. set(handles.TextOverlapThreshold, 'Enable', 'on'); set(findall(handles.PanelFilterPadding, '-property', 'Enable'), 'Enable', 'off'); set(handles.TextboxPaddingLength, 'Enable', 'off'); set(handles.TextPaddingLength, 'Enable', 'off'); end % Set output handles: handles.time = time; handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load epoch & pad length settings: ---% %-----------------------------------------% function OutputHandles = LoadEpochSettings(InputHandles, LoadedMat) handles = InputHandles; time = handles.time; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.DefineTrial.trialfun = LoadedMat.FTcfg.DefineTrial.trialfun; FTcfg.DefineTrial.trialdef.prestim = LoadedMat.FTcfg.DefineTrial.trialdef.prestim; FTcfg.DefineTrial.trialdef.poststim = LoadedMat.FTcfg.DefineTrial.trialdef.poststim; FTcfg.Preproc.padding = LoadedMat.FTcfg.Preproc.padding; time.Start = LoadedMat.time.Start; time.End = LoadedMat.time.End; time.OverlapThresh = LoadedMat.time.OverlapThresh; time.IncEventStart = LoadedMat.time.IncEventStart; time.IncEventEnd = LoadedMat.time.IncEventEnd; time.ExcEventStart = LoadedMat.time.ExcEventStart; time.ExcEventEnd = LoadedMat.time.ExcEventEnd; % Load GUI panel: set(handles.TextboxPrestimTime, 'String', num2str(FTcfg.DefineTrial.trialdef.prestim)); set(handles.TextboxPoststimTime, 'String', num2str(FTcfg.DefineTrial.trialdef.poststim)); set(handles.TextboxPaddingLength, 'String', num2str(FTcfg.Preproc.padding)); set(handles.TextboxOverlapThreshold, 'String', num2str(time.OverlapThresh, '%1.3f')); set(handles.TextboxIncEventStartTime, 'String', num2str(time.IncEventStart, '%1.3f')); set(handles.TextboxIncEventEndTime, 'String', num2str(time.IncEventEnd, '%1.3f')); set(handles.TextboxExcEventStartTime, 'String', num2str(time.ExcEventStart, '%1.3f')); set(handles.TextboxExcEventEndTime, 'String', num2str(time.ExcEventEnd, '%1.3f')); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset epoch & pad length settings: ---% %------------------------------------------% function OutputHandles = ResetEpochSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg default settings: FTcfg.DefineTrial.trialfun = 'ft_trialfun_general'; FTcfg.DefineTrial.trialdef.prestim = 0.500; FTcfg.DefineTrial.trialdef.poststim = 1.000; FTcfg.Preproc.padding = 2; time.Start = -0.500; time.End = 1.000; time.OverlapThresh = 0.500; time.IncEventStart = time.Start; time.IncEventEnd = time.End; time.ExcEventStart = time.Start; time.ExcEventEnd = time.End; % Reset GUI panel: set(handles.TextboxPrestimTime, 'String', num2str(0.500, '%1.3f')); set(handles.TextboxPoststimTime, 'String', num2str(1.000, '%1.3f')); set(handles.TextboxPaddingLength, 'String', num2str(2.000, '%1.3f')); set(handles.TextboxOverlapThreshold, 'String', num2str(time.OverlapThresh, '%1.3f')); set(handles.TextboxIncEventStartTime, 'String', num2str(time.IncEventStart, '%1.3f')); set(handles.TextboxIncEventEndTime, 'String', num2str(time.IncEventEnd, '%1.3f')); set(handles.TextboxExcEventStartTime, 'String', num2str(time.ExcEventStart, '%1.3f')); set(handles.TextboxExcEventEndTime, 'String', num2str(time.ExcEventEnd, '%1.3f')); % Set output handles: handles.time = time; handles.FTcfg = FTcfg; OutputHandles = handles; %=============================================% % FUNCTIONS FOR BASELINE CORRECTION SETTINGS: % %=============================================% %--- GUI functions for baseline correction: ---% %----------------------------------------------% function CheckboxDemean_Callback(hObject, eventdata, handles) handles = UpdateBaselineSettings(handles); guidata(hObject, handles); function CheckboxBaselineWholeTrial_Callback(hObject, eventdata, handles) handles = UpdateBaselineSettings(handles); guidata(hObject, handles); %--- Textbox for user to enter baseline start time: ---% %------------------------------------------------------% function TextboxBaselineStart_Callback(hObject, eventdata, handles) if get(handles.CheckboxDemean, 'Value') == 1 BaselineStart = str2num(get(handles.TextboxBaselineStart, 'String')); BaselineEnd = str2num(get(handles.TextboxBaselineEnd, 'String')); if isempty(BaselineStart) msgbox('Error: Baseline start time not specified.', 'Error:'); set(handles.TextboxBaselineStart, 'String', num2str(handles.time.Start, '%1.3f')); return; end if (BaselineStart < handles.time.Start) || (BaselineStart > handles.time.End) msgbox('Error: Baseline time is outside bounds of epoch time.', 'Error:'); set(handles.TextboxBaselineStart, 'String', num2str(handles.time.Start, '%1.3f')); return; end if BaselineStart > BaselineEnd msgbox('Error: Baseline start cannot be greater than end time.', 'Error:'); set(handles.TextboxBaselineStart, 'String', num2str(handles.time.Start, '%1.3f')); set(handles.TextboxBaselineEnd, 'String', num2str(0, '%1.3f')); return; end end handles = UpdateBaselineSettings(handles); guidata(hObject, handles); %--- Textbox for user to enter baseline end time: ---% %----------------------------------------------------% function TextboxBaselineEnd_Callback(hObject, eventdata, handles) if get(handles.CheckboxDemean, 'Value') == 1 BaselineStart = str2num(get(handles.TextboxBaselineStart, 'String')); BaselineEnd = str2num(get(handles.TextboxBaselineEnd, 'String')); if isempty(BaselineEnd) msgbox('Error: Baseline end time not specified.', 'Error:'); set(handles.TextboxBaselineEnd, 'String', num2str(0, '%1.3f')); return; end if (BaselineEnd > handles.time.End) || (BaselineEnd < handles.time.Start) msgbox('Error: Baseline time is outside bounds of epoch time.', 'Error:'); set(handles.TextboxBaselineEnd, 'String', num2str(0, '%1.3f')); return; end if BaselineEnd < BaselineStart msgbox('Error: Baseline end cannot be less than start time.', 'Error:'); set(handles.TextboxBaselineEnd, 'String', num2str(0, '%1.3f')); set(handles.TextboxBaselineStart, 'String', num2str(handles.time.Start, '%1.3f')); return; end end handles = UpdateBaselineSettings(handles); guidata(hObject, handles); %--- Updates baseline settings & GUI panel: ---% %----------------------------------------------% function OutputHandles = UpdateBaselineSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxDemean, 'Value') == 1 FTcfg.Preproc.demean = 'yes'; if get(handles.CheckboxBaselineWholeTrial, 'Value') == 1 FTcfg.Preproc.baselinewindow = 'all'; else BaselineStart = str2num(get(handles.TextboxBaselineStart, 'String')); BaselineEnd = str2num(get(handles.TextboxBaselineEnd, 'String')); FTcfg.Preproc.baselinewindow = [BaselineStart, BaselineEnd]; end else FTcfg.Preproc.demean = 'no'; FTcfg.Preproc.baselinewindow = []; end % Enable/Disable GUI baseline components: if get(handles.CheckboxDemean, 'Value') == 1 set(findall(handles.PanelBaselineCorrection, '-property', 'Enable'), 'Enable', 'on'); if get(handles.CheckboxBaselineWholeTrial, 'Value') == 1 set(handles.TextboxBaselineStart, 'Enable', 'off'); set(handles.TextboxBaselineEnd, 'Enable', 'off'); set(handles.TextBaselineStart, 'Enable', 'off'); % Text header set(handles.TextBaselineEnd, 'Enable', 'off'); % Text header end else set(findall(handles.PanelBaselineCorrection, '-property', 'Enable'), 'Enable', 'off'); set(handles.CheckboxDemean, 'Enable', 'on'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelBaselineCorrection, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load baseline settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = LoadBaselineSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.demean = LoadedMat.FTcfg.Preproc.demean; FTcfg.Preproc.baselinewindow = LoadedMat.FTcfg.Preproc.baselinewindow; % Load GUI panel: if strcmp(FTcfg.Preproc.demean, 'yes') set(handles.CheckboxDemean, 'Value', 1); if strcmp(FTcfg.Preproc.baselinewindow, 'all') set(handles.CheckboxBaselineWholeTrial, 'Value', 1); set(handles.TextboxBaselineStart, 'String', []); set(handles.TextboxBaselineEnd, 'String', []); else BaselineStart = num2str(FTcfg.Preproc.baselinewindow(1)); BaselineEnd = num2str(FTcfg.Preproc.baselinewindow(2)); set(handles.CheckboxBaselineWholeTrial, 'Value', 0); set(handles.TextboxBaselineStart, 'String', BaselineStart); set(handles.TextboxBaselineEnd, 'String', BaselineEnd); end else set(handles.CheckboxDemean, 'Value', 0); set(handles.CheckboxBaselineWholeTrial, 'Value', 0); set(handles.TextboxBaselineStart, 'String', []); set(handles.TextboxBaselineEnd, 'String', []); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset baseline settings & GUI panel: ---% %--------------------------------------------% function OutputHandles = ResetBaselineSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.demean = 'yes'; FTcfg.Preproc.baselinewindow = [-0.500, -0.050]; % Reset GUI panel: set(handles.CheckboxDemean, 'Value', 1); set(handles.CheckboxBaselineWholeTrial, 'Value', 0); set(handles.TextboxBaselineStart, 'String', num2str(-0.500, '%1.3f')); set(handles.TextboxBaselineEnd, 'String', num2str(-0.050, '%1.3f')); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %========================================% % FUNCTIONS FOR GENERAL FILTER SETTINGS: % %========================================% %--- GUI functions for general filter: ---% %-----------------------------------------% function CheckboxPassFilter_Callback(hObject, eventdata, handles) handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); function PanelPassFilter_SelectionChangeFcn(hObject, eventdata, handles) handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); function DropdownPassFilterType_Callback(hObject, eventdata, handles) handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); function DropdownPassFilterDir_Callback(hObject, eventdata, handles) handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); function DropdownPassFilterInstability_Callback(hObject, eventdata, handles) handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); % Textbox for high-pass frequency: function TextboxHighpassFreq_Callback(hObject, eventdata, handles) Highpass = str2num(get(handles.TextboxHighpassFreq, 'String')); Lowpass = str2num(get(handles.TextboxLowpassFreq, 'String')); if isempty(Highpass) msgbox('Note: High-pass freq. not selected. Default set to 0.5.'); set(handles.TextboxHighpassFreq, 'String', num2str(0.5)); end if get(handles.ButtonBandpassFilter, 'Value') == 1 && Highpass > Lowpass msgbox('Error: High-pass freq. cannot be greater than low-pass.', 'Error:'); set(handles.TextboxHighpassFreq, 'String', num2str(0.5)); set(handles.TextboxLowpassFreq, 'String', num2str(55)); end handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); % Textbox for low-pass frequency: function TextboxLowpassFreq_Callback(hObject, eventdata, handles) Highpass = str2num(get(handles.TextboxHighpassFreq, 'String')); Lowpass = str2num(get(handles.TextboxLowpassFreq, 'String')); if isempty(Lowpass) msgbox('Note: Low-pass freq. not selected. Default set to 55.'); set(handles.TextboxLowpassFreq, 'String', num2str(55)); end if get(handles.ButtonBandpassFilter, 'Value') == 1 && Lowpass < Highpass msgbox('Error: Low-pass freq. cannot be less than high-pass.', 'Error:'); set(handles.TextboxHighpassFreq, 'String', num2str(0.5)); set(handles.TextboxLowpassFreq, 'String', num2str(55)); end handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); % Textbox for general filter-order: function TextboxPassFilterOrder_Callback(hObject, eventdata, handles) if isempty(get(handles.TextboxPassFilterOrder, 'String')) msgbox('Note: Filter-order not selected. Default set to 4.'); set(handles.TextboxPassFilterOrder, 'String', num2str(4)); end handles = UpdateGeneralFilterSettings(handles); guidata(hObject, handles); %--- Updates general filter settings & GUI panel: ---% %----------------------------------------------------% function OutputHandles = UpdateGeneralFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxPassFilter, 'Value') == 1 HighPass = str2num(get(handles.TextboxHighpassFreq, 'String')); LowPass = str2num(get(handles.TextboxLowpassFreq, 'String')); if get(handles.ButtonBandpassFilter, 'Value') == 1 FTcfg.Preproc.bpfilter = 'yes'; FTcfg.Preproc.hpfilter = 'no'; FTcfg.Preproc.lpfilter = 'no'; FTcfg.Preproc.bpfreq = [HighPass, LowPass]; FTcfg.Preproc.hpfreq = []; FTcfg.Preproc.lpfreq = []; elseif get(handles.ButtonHighpassFilter, 'Value') == 1 FTcfg.Preproc.bpfilter = 'no'; FTcfg.Preproc.hpfilter = 'yes'; FTcfg.Preproc.lpfilter = 'no'; FTcfg.Preproc.bpfreq = []; FTcfg.Preproc.hpfreq = HighPass; FTcfg.Preproc.lpfreq = []; elseif get(handles.ButtonLowpassFilter, 'Value') == 1 FTcfg.Preproc.bpfilter = 'no'; FTcfg.Preproc.hpfilter = 'no'; FTcfg.Preproc.lpfilter = 'yes'; FTcfg.Preproc.bpfreq = []; FTcfg.Preproc.hpfreq = []; FTcfg.Preproc.lpfreq = LowPass; end else FTcfg.Preproc.bpfilter = 'no'; FTcfg.Preproc.hpfilter = 'no'; FTcfg.Preproc.lpfilter = 'no'; FTcfg.Preproc.bpfreq = []; FTcfg.Preproc.hpfreq = []; FTcfg.Preproc.lpfreq = []; end DropdownOptions = get(handles.DropdownPassFilterDir, 'String'); PassFilterDir = DropdownOptions{get(handles.DropdownPassFilterDir, 'Value')}; switch PassFilterDir case 'Twopass' FTcfg.Preproc.bpfiltdir = 'twopass'; FTcfg.Preproc.hpfiltdir = 'twopass'; FTcfg.Preproc.lpfiltdir = 'twopass'; case 'Onepass' FTcfg.Preproc.bpfiltdir = 'onepass'; FTcfg.Preproc.hpfiltdir = 'onepass'; FTcfg.Preproc.lpfiltdir = 'onepass'; case 'Onepass-Reverse' FTcfg.Preproc.bpfiltdir = 'onepass-reverse'; FTcfg.Preproc.hpfiltdir = 'onepass-reverse'; FTcfg.Preproc.lpfiltdir = 'onepass-reverse'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownPassFilterType, 'String'); PassFilterType = DropdownOptions{get(handles.DropdownPassFilterType, 'Value')}; switch PassFilterType case 'Butterworth' FTcfg.Preproc.bpfilttype = 'but'; FTcfg.Preproc.hpfilttype = 'but'; FTcfg.Preproc.lpfilttype = 'but'; case 'FIR' FTcfg.Preproc.bpfilttype = 'fir'; FTcfg.Preproc.hpfilttype = 'fir'; FTcfg.Preproc.lpfilttype = 'fir'; case 'FIRLS' FTcfg.Preproc.bpfilttype = 'firls'; FTcfg.Preproc.hpfilttype = 'firls'; FTcfg.Preproc.lpfilttype = 'firls'; otherwise error('Unrecognized Option'); % error-check end PassFilterOrder = str2num(get(handles.TextboxPassFilterOrder, 'String')); switch PassFilterType case 'Butterworth' FTcfg.Preproc.bpfiltord = PassFilterOrder; FTcfg.Preproc.hpfiltord = PassFilterOrder; FTcfg.Preproc.lpfiltord = PassFilterOrder; case {'FIR', 'FIRLS'} FTcfg.Preproc.bpfiltord = []; FTcfg.Preproc.hpfiltord = []; FTcfg.Preproc.lpfiltord = []; end DropdownOptions = get(handles.DropdownPassFilterInstability, 'String'); PassFilterFix = DropdownOptions{get(handles.DropdownPassFilterInstability, 'Value')}; switch PassFilterFix case 'Detect Only' FTcfg.Preproc.bpinstabilityfix = 'no'; FTcfg.Preproc.hpinstabilityfix = 'no'; FTcfg.Preproc.lpinstabilityfix = 'no'; case 'Reduce Filter Order' FTcfg.Preproc.bpinstabilityfix = 'reduce'; FTcfg.Preproc.hpinstabilityfix = 'reduce'; FTcfg.Preproc.lpinstabilityfix = 'reduce'; case 'Split Filter' FTcfg.Preproc.bpinstabilityfix = 'split'; FTcfg.Preproc.hpinstabilityfix = 'split'; FTcfg.Preproc.lpinstabilityfix = 'split'; otherwise error('Unrecognized Option'); % error-check end % Enable/Disable GUI components: if get(handles.CheckboxPassFilter, 'Value') == 1 set(findall(handles.PanelPassFilter, '-property', 'Enable'), 'Enable', 'on'); if get(handles.ButtonHighpassFilter, 'Value') == 1 set(handles.TextboxLowpassFreq, 'Enable', 'off'); set(handles.TextLowpassFreq, 'Enable', 'off'); % Text header elseif get(handles.ButtonLowpassFilter, 'Value') ==1 set(handles.TextboxHighpassFreq, 'Enable', 'off'); set(handles.TextHighpassFreq, 'Enable', 'off'); % Text header end if ismember(PassFilterType, {'FIR', 'FIRLS'}) set(handles.TextboxPassFilterOrder, 'Enable', 'off'); set(handles.TextPassFilterOrder, 'Enable', 'off'); % Text header end else set(findall(handles.PanelPassFilter, '-property', 'Enable'), 'Enable', 'off'); set(handles.CheckboxPassFilter, 'Enable', 'on'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelPassFilter, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load general filter settings & GUI panel: ---% %-------------------------------------------------% function OutputHandles = LoadGeneralFilterSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.bpfilter = LoadedMat.FTcfg.Preproc.bpfilter; FTcfg.Preproc.hpfilter = LoadedMat.FTcfg.Preproc.hpfilter; FTcfg.Preproc.lpfilter = LoadedMat.FTcfg.Preproc.lpfilter; FTcfg.Preproc.bpfreq = LoadedMat.FTcfg.Preproc.bpfreq; FTcfg.Preproc.hpfreq = LoadedMat.FTcfg.Preproc.hpfreq; FTcfg.Preproc.lpfreq = LoadedMat.FTcfg.Preproc.lpfreq; FTcfg.Preproc.bpfiltdir = LoadedMat.FTcfg.Preproc.bpfiltdir; FTcfg.Preproc.hpfiltdir = LoadedMat.FTcfg.Preproc.hpfiltdir; FTcfg.Preproc.lpfiltdir = LoadedMat.FTcfg.Preproc.lpfiltdir; FTcfg.Preproc.bpfilttype = LoadedMat.FTcfg.Preproc.bpfilttype; FTcfg.Preproc.hpfilttype = LoadedMat.FTcfg.Preproc.hpfilttype; FTcfg.Preproc.lpfilttype = LoadedMat.FTcfg.Preproc.lpfilttype; FTcfg.Preproc.bpfiltord = LoadedMat.FTcfg.Preproc.bpfiltord; FTcfg.Preproc.hpfiltord = LoadedMat.FTcfg.Preproc.hpfiltord; FTcfg.Preproc.lpfiltord = LoadedMat.FTcfg.Preproc.lpfiltord; FTcfg.Preproc.bpinstabilityfix = LoadedMat.FTcfg.Preproc.bpinstabilityfix; FTcfg.Preproc.hpinstabilityfix = LoadedMat.FTcfg.Preproc.hpinstabilityfix; FTcfg.Preproc.lpinstabilityfix = LoadedMat.FTcfg.Preproc.lpinstabilityfix; % Load GUI general filter: if strcmp(FTcfg.Preproc.bpfilter, 'yes') set(handles.CheckboxPassFilter, 'Value', 1); set(handles.ButtonBandpassFilter, 'Value', 1); set(handles.TextboxHighpassFreq, 'String', num2str(FTcfg.Preproc.bpfreq(1))); set(handles.TextboxLowpassFreq, 'String', num2str(FTcfg.Preproc.bpfreq(2))); elseif strcmp(FTcfg.Preproc.hpfilter, 'yes') set(handles.CheckboxPassFilter, 'Value', 1); set(handles.ButtonHighpassFilter, 'Value', 1); set(handles.TextboxHighpassFreq, 'String', num2str(FTcfg.Preproc.hpfreq)); set(handles.TextboxLowpassFreq, 'String', []); elseif strcmp(FTcfg.Preproc.lpfilter, 'yes') set(handles.CheckboxPassFilter, 'Value', 1); set(handles.ButtonLowpassFilter, 'Value', 1); set(handles.TextboxHighpassFreq, 'String', []); set(handles.TextboxLowpassFreq, 'String', num2str(FTcfg.Preproc.lpfreq)); elseif strcmp(FTcfg.Preproc.bpfilter, 'no') &&... strcmp(FTcfg.Preproc.hpfilter, 'no') &&... strcmp(FTcfg.Preproc.lpfilter, 'no') set(handles.CheckboxPassFilter, 'Value', 0); set(handles.TextboxHighpassFreq, 'String', []); set(handles.TextboxLowpassFreq, 'String', []); end % Load GUI filter direction: switch FTcfg.Preproc.bpfiltdir case 'twopass' PassFilterDir = 'Twopass'; case 'onepass' PassFilterDir = 'Onepass'; case 'onepass-reverse' PassFilterDir = 'Onepass-Reverse'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownPassFilterDir, 'String'); DropdownValue = find(strcmp(DropdownOptions, PassFilterDir)); set(handles.DropdownPassFilterDir, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Load GUI filter type: switch FTcfg.Preproc.bpfilttype case 'but' PassFilterType = 'Butterworth'; set(handles.TextboxPassFilterOrder, 'String', num2str(FTcfg.Preproc.bpfiltord)); case 'fir' PassFilterType = 'FIR'; set(handles.TextboxPassFilterOrder, 'String', []); case 'firls' PassFilterType = 'FIRLS'; set(handles.TextboxPassFilterOrder, 'String', []); otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownPassFilterType, 'String'); DropdownValue = find(strcmp(DropdownOptions, PassFilterType)); set(handles.DropdownPassFilterType, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Load GUI filter instability: switch FTcfg.Preproc.bpinstabilityfix case 'no' PassFilterFix = 'Detect Only'; case 'reduce' PassFilterFix = 'Reduce Filter Only'; case 'split' PassFilterFix = 'Split Filter'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownPassFilterInstability, 'String'); DropdownValue = find(strcmp(DropdownOptions, PassFilterFix)); set(handles.DropdownPassFilterInstability, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset general filter settings & GUI panel: ---% %--------------------------------------------------% function OutputHandles = ResetGeneralFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.bpfilter = 'yes'; FTcfg.Preproc.hpfilter = 'no'; FTcfg.Preproc.lpfilter = 'no'; FTcfg.Preproc.bpfreq = [0.5, 55]; FTcfg.Preproc.hpfreq = []; FTcfg.Preproc.lpfreq = []; FTcfg.Preproc.bpfiltdir = 'twopass'; FTcfg.Preproc.hpfiltdir = 'twopass'; FTcfg.Preproc.lpfiltdir = 'twopass'; FTcfg.Preproc.bpfilttype = 'but'; FTcfg.Preproc.hpfilttype = 'but'; FTcfg.Preproc.lpfilttype = 'but'; FTcfg.Preproc.bpfiltord = 4; FTcfg.Preproc.hpfiltord = 4; FTcfg.Preproc.lpfiltord = 4; FTcfg.Preproc.bpinstabilityfix = 'no'; FTcfg.Preproc.hpinstabilityfix = 'no'; FTcfg.Preproc.lpinstabilityfix = 'no'; % Reset GUI panel: set(handles.CheckboxPassFilter, 'Value', 1); set(handles.ButtonBandpassFilter, 'Value', 1); set(handles.ButtonHighpassFilter, 'Value', 0); set(handles.ButtonLowpassFilter, 'Value', 0); set(handles.TextboxHighpassFreq, 'String', num2str(0.5)); set(handles.TextboxLowpassFreq, 'String', num2str(55)); set(handles.DropdownPassFilterDir, 'Value', 1); set(handles.DropdownPassFilterType, 'Value', 1); set(handles.TextboxPassFilterOrder, 'String', num2str(4)); set(handles.DropdownPassFilterInstability, 'Value', 1); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %=========================================% % FUNCTIONS FOR BANDSTOP FILTER SETTINGS: % %=========================================% %--- GUI functions for bandstop filter: ---% %------------------------------------------% function CheckboxBandstopFilter_Callback(hObject, eventdata, handles) handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); function DropdownBandstopFilterType_Callback(hObject, eventdata, handles) handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); function DropdownBandstopFilterDir_Callback(hObject, eventdata, handles) handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); function DropdownBandstopFilterInstability_Callback(hObject, eventdata, handles) handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); % Textbox for high-stop frequency: function TextboxHighstopFreq_Callback(hObject, eventdata, handles) Highstop = str2num(get(handles.TextboxHighstopFreq, 'String')); Lowstop = str2num(get(handles.TextboxLowstopFreq, 'String')); if isempty(Highstop) msgbox('Note: High-stop freq. not specified. Resetting value.'); set(handles.TextboxHighstopFreq, 'String', num2str(59)); end if Highstop > Lowstop msgbox('Error: High-stop freq. cannot be greater than low-stop.', 'Error:'); set(handles.TextboxHighstopFreq, 'String', num2str(59)); set(handles.TextboxLowstopFreq, 'String', num2str(61)); end handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); % Textbox for low-stop frequency: function TextboxLowstopFreq_Callback(hObject, eventdata, handles) Highstop = str2num(get(handles.TextboxHighstopFreq, 'String')); Lowstop = str2num(get(handles.TextboxLowstopFreq, 'String')); if isempty(Lowstop) msgbox('Note: Low-stop freq. not specified. Resetting value.'); set(handles.TextboxLowstopFreq, 'String', num2str(61)); end if Lowstop < Highstop msgbox('Error: Low-stop freq. cannot be less than high-stop.', 'Error:'); set(handles.TextboxHighstopFreq, 'String', num2str(59)); set(handles.TextboxLowstopFreq, 'String', num2str(61)); end handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); % Textbox for stop-filter order: function TextboxBandstopFilterOrder_Callback(hObject, eventdata, handles) if isempty(get(handles.TextboxBandstopFilterOrder, 'String')) msgbox('Note: Bandstop filter order not specified. Default set to 4.'); set(handles.TextboxBandstopFilterOrder, 'String', num2str(4)); end handles = UpdateBandstopFilterSettings(handles); guidata(hObject, handles); %--- Updates bandstop filter settings & GUI panel: ---% %-----------------------------------------------------% function OutputHandles = UpdateBandstopFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxBandstopFilter, 'Value') == 1 FTcfg.Preproc.bsfilter = 'yes'; FTcfg.Preproc.bsfreq = [str2num(get(handles.TextboxHighstopFreq, 'String')),... str2num(get(handles.TextboxLowstopFreq, 'String'))]; else FTcfg.Preproc.bsfilter = 'no'; FTcfg.Preproc.bsfreq = []; end DropdownOptions = get(handles.DropdownBandstopFilterDir, 'String'); BandstopFilterDir = DropdownOptions{get(handles.DropdownBandstopFilterDir, 'Value')}; switch BandstopFilterDir case 'Twopass' FTcfg.Preproc.bsfiltdir = 'twopass'; case 'Onepass' FTcfg.Preproc.bsfiltdir = 'onepass'; case 'Onepass-Reverse' FTcfg.Preproc.bsfiltdir = 'onepass-reverse'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownBandstopFilterType, 'String'); BandstopFilterType = DropdownOptions{get(handles.DropdownBandstopFilterType, 'Value')}; switch BandstopFilterType case 'Butterworth' FTcfg.Preproc.bsfilttype = 'but'; case 'FIR' FTcfg.Preproc.bsfilttype = 'fir'; case 'FIRLS' FTcfg.Preproc.bsfilttype = 'firls'; otherwise error('Unrecognized Option'); % error-check end BandstopFilterOrder = str2num(get(handles.TextboxBandstopFilterOrder, 'String')); switch BandstopFilterType case 'Butterworth' FTcfg.Preproc.bsfiltord = BandstopFilterOrder; case {'FIR', 'FIRLS'} FTcfg.Preproc.bsfiltord = []; end DropdownOptions = get(handles.DropdownBandstopFilterInstability, 'String'); BandstopFilterFix = DropdownOptions{get(handles.DropdownBandstopFilterInstability, 'Value')}; switch BandstopFilterFix case 'Detect Only' FTcfg.Preproc.bsinstabilityfix = 'no'; case 'Reduce Filter Order' FTcfg.Preproc.bsinstabilityfix = 'reduce'; case 'Split Filter' FTcfg.Preproc.bsinstabilityfix = 'split'; otherwise error('Unrecognized Option'); % error-check end % Enable/Disable GUI components: if get(handles.CheckboxBandstopFilter, 'Value') == 1 set(findall(handles.PanelBandstopFilter, '-property', 'Enable'), 'Enable', 'on'); if ismember(BandstopFilterType, {'FIR', 'FIRLS'}) set(handles.TextboxBandstopFilterOrder, 'Enable', 'off'); set(handles.TextBandstopFilterOrder, 'Enable', 'off'); % Text header end else set(findall(handles.PanelBandstopFilter, '-property', 'Enable'), 'Enable', 'off'); set(handles.CheckboxBandstopFilter, 'Enable', 'on'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelBandstopFilter, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load bandstop filter settings & GUI panel: ---% %--------------------------------------------------% function OutputHandles = LoadBandstopFilterSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.bsfilter = LoadedMat.FTcfg.Preproc.bsfilter; FTcfg.Preproc.bsfreq = LoadedMat.FTcfg.Preproc.bsfreq; FTcfg.Preproc.bsfiltdir = LoadedMat.FTcfg.Preproc.bsfiltdir; FTcfg.Preproc.bsfilttype = LoadedMat.FTcfg.Preproc.bsfilttype; FTcfg.Preproc.bsfiltord = LoadedMat.FTcfg.Preproc.bsfiltord; FTcfg.Preproc.bsinstabilityfix = LoadedMat.FTcfg.Preproc.bsinstabilityfix; % Load GUI components: if strcmp(FTcfg.Preproc.bsfilter, 'yes') set(handles.CheckboxBandstopFilter, 'Value', 1); set(handles.TextboxHighstopFreq, 'String', num2str(FTcfg.Preproc.bsfreq(1))); set(handles.TextboxLowstopFreq, 'String', num2str(FTcfg.Preproc.bsfreq(2))); else set(handles.CheckboxBandstopFilter, 'Value', 0); set(handles.TextboxHighstopFreq, 'String', []); set(handles.TextboxLowstopFreq, 'String', []); end % Load GUI filter direction: switch FTcfg.Preproc.bsfiltdir case 'twopass' BandstopFilterDir = 'Twopass'; case 'onepass' BandstopFilterDir = 'Onepass'; case 'onepass-reverse' BandstopFilterDir = 'Onepass-Reverse'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownBandstopFilterDir, 'String'); DropdownValue = find(strcmp(DropdownOptions, BandstopFilterDir)); set(handles.DropdownBandstopFilterDir, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Load GUI filter type: switch FTcfg.Preproc.bsfilttype case 'but' BandstopFilterType = 'Butterworth'; set(handles.TextboxBandstopFilterOrder, 'String', num2str(FTcfg.Preproc.bsfiltord)); case 'fir' BandstopFilterType = 'FIR'; set(handles.TextboxBandstopFilterOrder, 'String', []); case 'firls' BandstopFilterType = 'FIRLS'; set(handles.TextboxBandstopFilterOrder, 'String', []); otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownBandstopFilterType, 'String'); DropdownValue = find(strcmp(DropdownOptions, BandstopFilterType)); set(handles.DropdownBandstopFilterType, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Load GUI instability fix: switch FTcfg.Preproc.bsinstabilityfix case 'no' BandstopFilterFix = 'Detect Only'; case 'reduce' BandstopFilterFix = 'Reduce Filter Order'; case 'split' BandstopFilterFix = 'Split Filter'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownBandstopFilterInstability, 'String'); DropdownValue = find(strcmp(DropdownOptions, BandstopFilterFix)); set(handles.DropdownBandstopFilterInstability, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset bandstop filter settings & GUI panel: ---% %---------------------------------------------------% function OutputHandles = ResetBandstopFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.bsfilter = 'no'; FTcfg.Preproc.bsfreq = []; FTcfg.Preproc.bsfiltdir = 'twopass'; FTcfg.Preproc.bsfilttype = 'but'; FTcfg.Preproc.bsfiltord = 4; FTcfg.Preproc.bsinstabilityfix = 'no'; % Reset GUI panel: set(handles.CheckboxBandstopFilter, 'Value', 0); set(handles.TextboxHighstopFreq, 'String', []); set(handles.TextboxLowstopFreq, 'String', []); set(handles.DropdownBandstopFilterDir, 'Value', 1); set(handles.DropdownBandstopFilterType, 'Value', 1); set(handles.TextboxBandstopFilterOrder, 'String', num2str(4)); set(handles.DropdownBandstopFilterInstability, 'Value', 1); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %====================================% % FUNCTIONS FOR DFT FILTER SETTINGS: % %====================================% %--- GUI functions for DFT filter: ---% %-------------------------------------% function CheckboxDFT_Callback(hObject, eventdata, handles) handles = UpdateDFTFilterSettings(handles); guidata(hObject, handles); function PanelDFT_SelectionChangeFcn(hObject, eventdata, handles) handles = UpdateDFTFilterSettings(handles); guidata(hObject, handles); function TextboxDFTcustom_Callback(hObject, eventdata, handles) if isempty(get(handles.TextboxDFTcustom, 'String')) msgbox('Note: Custom DFT filter frequency not specified. Set to default value.') set(handles.TextboxDFTcustom, 'String', '60, 120, 180'); end handles = UpdateDFTFilterSettings(handles); guidata(hObject, handles); %--- Updates DFT filter settings & GUI panel: ---% %------------------------------------------------% function OutputHandles = UpdateDFTFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxDFT, 'Value') == 1 FTcfg.Preproc.dftfilter = 'yes'; if get(handles.ButtonDFTdefault, 'Value') == 1 FTcfg.Preproc.dftfreq = [60, 120, 180]; elseif get(handles.ButtonDFTeuropean, 'Value') == 1 FTcfg.Preproc.dftfreq = [50, 100, 150]; elseif get(handles.ButtonDFTcustom, 'Value') == 1 FTcfg.Preproc.dftfreq = [str2num(get(handles.TextboxDFTcustom, 'String'))]; end else FTcfg.Preproc.dftfilter = 'no'; FTcfg.Preproc.dftfreq = []; end % Enable/Disable GUI components: if get(handles.CheckboxDFT, 'Value') == 1 set(findall(handles.PanelDFT, '-property', 'Enable'), 'Enable', 'on'); if get(handles.ButtonDFTcustom, 'Value') == 0 set(handles.TextboxDFTcustom, 'Enable', 'off'); end else set(findall(handles.PanelDFT, '-property', 'Enable'), 'Enable', 'off'); set(handles.CheckboxDFT, 'Enable', 'on'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelDFT, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load DFT filter settings & GUI panel: ---% %---------------------------------------------% function OutputHandles = LoadDFTFilterSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.dftfilter = LoadedMat.FTcfg.Preproc.dftfilter; FTcfg.Preproc.dftfreq = LoadedMat.FTcfg.Preproc.dftfreq; % Load GUI panel: if strcmp(FTcfg.Preproc.dftfilter, 'yes') set(handles.CheckboxDFT, 'Value', 1); if isequal(FTcfg.Preproc.dftfreq, [60, 120, 180]) set(handles.ButtonDFTdefault, 'Value', 1); set(handles.TextboxDFTcustom, 'String', []); elseif isequal(FTcfg.Preproc.dftfreq, [50, 100, 150]) set(handles.ButtonDFTeuropean, 'Value', 1); set(handles.TextboxDFTcustom, 'String', []); else set(handles.ButtonDFTcustom, 'Value', 1); set(handles.TextboxDFTcustom, 'String', num2str(FTcfg.Preproc.dftfreq)); end else set(handles.CheckboxDFT, 'Value', 0); set(handles.ButtonDFTdefault, 'Value', 1); set(handles.ButtonDFTeuropean, 'Value', 0); set(handles.ButtonDFTcustom, 'Value', 0); set(handles.TextboxDFTcustom, 'String', []); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset DFT filter settings & GUI panel: ---% %----------------------------------------------% function OutputHandles = ResetDFTFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.dftfilter = 'yes'; FTcfg.Preproc.dftfreq = [60, 120, 180]; % Reset GUI panel: set(handles.CheckboxDFT, 'Value', 1); set(handles.ButtonDFTdefault, 'Value', 1); set(handles.ButtonDFTeuropean, 'Value', 0); set(handles.ButtonDFTcustom, 'Value', 0); set(handles.TextboxDFTcustom, 'String', []); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %=======================================% % FUNCTIONS FOR MEDIAN FILTER SETTINGS: % %=======================================% %--- GUI functions for median filter: ---% %----------------------------------------% function CheckboxMedianFilter_Callback(hObject, eventdata, handles) handles = UpdateMedianFilterSettings(handles); guidata(hObject, handles); function TextboxMedianFilterOrder_Callback(hObject, eventdata, handles) if isempty(get(handles.TextboxMedianFilterOrder, 'String')) msgbox('Note: Median filter order not set. Default set to 9.'); set(handles.TextboxMedianFilterOrder, 'String', num2str(9)); end handles = UpdateMedianFilterSettings(handles); guidata(hObject, handles); %--- Updates median filter settings & GUI panel: ---% %---------------------------------------------------% function OutputHandles = UpdateMedianFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxMedianFilter, 'Value') == 1 FTcfg.Preproc.medianfilter = 'yes'; FTcfg.Preproc.medianfiltord = str2num(get(handles.TextboxMedianFilterOrder, 'String')); else FTcfg.Preproc.medianfilter = 'no'; FTcfg.Preproc.medianfiltord = []; end % Enable/Disable GUI components: if get(handles.CheckboxMedianFilter, 'Value') == 1 set(findall(handles.PanelMedianFilter, '-property', 'Enable'), 'Enable', 'on'); else set(findall(handles.PanelMedianFilter, '-property', 'Enable'), 'Enable', 'off'); set(handles.CheckboxMedianFilter, 'Enable', 'on'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelMedianFilter, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load median filter settings & GUI panel: ---% %------------------------------------------------% function OutputHandles = LoadMedianFilterSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.medianfilter = LoadedMat.FTcfg.Preproc.medianfilter; FTcfg.Preproc.medianfiltord = LoadedMat.FTcfg.Preproc.medianfiltord; % Load GUI panel: if strcmp(FTcfg.Preproc.medianfilter, 'yes') set(handles.CheckboxMedianFilter, 'Value', 1); set(handles.TextboxMedianFilterOrder, 'String', num2str(FTcfg.Preproc.medianfiltord)); else set(handles.CheckboxMedianFilter, 'Value', 0); set(handles.TextboxMedianFilterOrder, 'String', []); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset DFT filter settings & GUI panel: ---% %----------------------------------------------% function OutputHandles = ResetMedianFilterSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.medianfilter = 'no'; FTcfg.Preproc.medianfiltord = 9; % Reset GUI panel: set(handles.CheckboxMedianFilter, 'Value', 0); set(handles.TextboxMedianFilterOrder, 'String', num2str(9)); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %=======================================% % FUNCTIONS FOR TREND REMOVAL SETTINGS: % %=======================================% %--- GUI functions for trend removal: ---% %----------------------------------------% function CheckboxDetrend_Callback(hObject, eventdata, handles) handles = UpdateDetrendSettings(handles); guidata(hObject, handles); function CheckboxPolyremoval_Callback(hObject, eventdata, handles) handles = UpdateDetrendSettings(handles); guidata(hObject, handles); function TextboxPolyremovalOrder_Callback(hObject, eventdata, handles) if isempty(get(handles.TextboxPolyremovalOrder, 'String')) msgbox('Note: Polyremoval order not specified. Default set to 2.'); set(handles.TextboxPolyremovalOrder, 'String', num2str(2)); end handles = UpdateDetrendSettings(handles); guidata(hObject, handles); %--- Updates trend removal settings & GUI panel: ---% %---------------------------------------------------% function OutputHandles = UpdateDetrendSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Read GUI to update FTcfg: if get(handles.CheckboxDetrend, 'Value') == 1 FTcfg.Preproc.detrend = 'yes'; else FTcfg.Preproc.detrend = 'no'; end if get(handles.CheckboxPolyremoval, 'Value') == 1 FTcfg.Preproc.polyremoval = 'yes'; FTcfg.Preproc.polyorder = str2num(get(handles.TextboxPolyremovalOrder, 'String')); else FTcfg.Preproc.polyremoval = 'no'; FTcfg.Preproc.polyorder = []; end % Enable/Disable GUI components: set(findall(handles.PanelDetrend, '-property', 'Enable'), 'Enable', 'on'); if get(handles.CheckboxPolyremoval, 'Value') == 0 set(handles.TextboxPolyremovalOrder, 'Enable', 'off'); set(handles.TextPolyremovalOrder, 'Enable', 'off'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelDetrend, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load trend removal settings & GUI panel: ---% %------------------------------------------------% function OutputHandles = LoadDetrendSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.Preproc.detrend = LoadedMat.FTcfg.Preproc.detrend; FTcfg.Preproc.polyremoval = LoadedMat.FTcfg.Preproc.polyremoval; FTcfg.Preproc.polyorder = LoadedMat.FTcfg.Preproc.polyorder; % Load GUI panel: if strcmp(FTcfg.Preproc.detrend, 'yes') set(handles.CheckboxDetrend, 'Value', 1); else set(handles.CheckboxDetrend, 'Value', 0); end if strcmp(FTcfg.Preproc.polyremoval, 'yes') set(handles.CheckboxPolyremoval, 'Value', 1); set(handles.TextboxPolyremovalOrder, 'String', num2str(FTcfg.Preproc.polyorder)); else set(handles.CheckboxPolyremoval, 'Value', 0); set(handles.TextboxPolyremovalOrder, 'String', []); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset trend removal settings & GUI panel: ---% %-------------------------------------------------% function OutputHandles = ResetDetrendSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.Preproc.detrend = 'no'; FTcfg.Preproc.polyremoval = 'no'; FTcfg.Preproc.polyorder = 2; % Reset GUI panel: set(handles.CheckboxDetrend, 'Value', 0); set(handles.CheckboxPolyremoval, 'Value', 0); set(handles.TextboxPolyremovalOrder, 'String', num2str(2)); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %==========================================% % FUNCTIONS FOR OTHER ADV. SETTINGS PANEL: % %==========================================% %--- GUI functions for other adv. settings: ---% %----------------------------------------------% function CheckboxGradCorrCTF_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); function DropdownGradCorrCTF_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); function CheckboxHilbert_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); function DropdownHilbert_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); function CheckboxRectify_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); function CheckboxDerivative_Callback(hObject, eventdata, handles) handles = UpdateOtherAdvSettings(handles); guidata(hObject, handles); %--- Updates other adv. settings & GUI panel: ---% %---------------------------------------------------% function OutputHandles = UpdateOtherAdvSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Check if options valid: if get(handles.CheckboxGradCorrCTF, 'Value') == 1 &&... ~strcmp(handles.gui.DataFiletype, 'CTFds') msgbox('Warning: CTF gradient correction is disabled for filetype.', 'Warning:'); set(handles.CheckboxGradCorrCTF, 'Value', 0); end if get(handles.CheckboxHilbert, 'Value') == 1 &&... get(handles.ButtonBandpassFilter, 'Value') == 0 msgbox('Warning: Hilbert transform must be run with bandpass filter.', 'Warning:'); set(handles.CheckboxHilbert, 'Value', 0); end if get(handles.CheckboxRectify, 'Value') == 1 &&... get(handles.CheckboxHilbert, 'Value') == 1 msgbox('Warning: Rectify data cannot be run with Hilbert transform.', 'Warning:'); set(handles.CheckboxRectify, 'Value', 0); end % Read GUI to update FTcfg: if get(handles.CheckboxGradCorrCTF, 'Value') == 1 DropdownOptions = get(handles.DropdownGradCorrCTF, 'String'); GradCorrType = DropdownOptions{get(handles.DropdownGradCorrCTF, 'Value')}; switch GradCorrType case 'First-Order' FTcfg.GradCorrectCTF.gradient = 'G1BR'; case 'Second-Order' FTcfg.GradCorrectCTF.gradient = 'G2BR'; case 'Third-Order' FTcfg.GradCorrectCTF.gradient = 'G3BR'; otherwise error('Unrecognized Option'); % error-check end FTcfg.GradCorrectCTF.trials = 'all'; else FTcfg.GradCorrectCTF = []; FTcfg.GradCorrectCTF = 'none'; end if get(handles.CheckboxHilbert, 'Value') == 1 DropdownOptions = get(handles.DropdownHilbert, 'String'); HilbertType = DropdownOptions{get(handles.DropdownHilbert, 'Value')}; FTcfg.Preproc.hilbert = HilbertType; else FTcfg.Preproc.hilbert = 'no'; end if get(handles.CheckboxRectify, 'Value') == 1 FTcfg.Preproc.rectify = 'yes'; else FTcfg.Preproc.rectify = 'no'; end if get(handles.CheckboxDerivative, 'Value') == 1 FTcfg.Preproc.derivative = 'yes'; else FTcfg.Preproc.derivative = 'no'; end % Enable/Disable GUI components: set(findall(handles.PanelOtherAdvOptions, '-property', 'Enable'), 'Enable', 'on'); if strcmp(handles.gui.DataFiletype, 'Fieldtrip') set(handles.CheckboxGradCorrCTF, 'Enable', 'off'); set(handles.DropdownGradCorrCTF, 'Enable', 'off'); end if get(handles.CheckboxGradCorrCTF, 'Value') == 0 set(handles.DropdownGradCorrCTF, 'Enable', 'off'); end if get(handles.CheckboxHilbert, 'Value') == 0 set(handles.DropdownHilbert, 'Enable', 'off'); end % Lock GUI panel if needed: if strcmp(handles.gui.LockPreprocSettings, 'on') set(findall(handles.PanelOtherAdvOptions, '-property', 'Enable'), 'Enable', 'off'); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Load other adv. settings & GUI panel: ---% %---------------------------------------------% function OutputHandles = LoadOtherAdvSettings(InputHandles, LoadedMat) handles = InputHandles; FTcfg = handles.FTcfg; % Load FTcfg settings: FTcfg.GradCorrectCTF = LoadedMat.FTcfg.GradCorrectCTF; FTcfg.Preproc.hilbert = LoadedMat.FTcfg.Preproc.hilbert; FTcfg.Preproc.rectify = LoadedMat.FTcfg.Preproc.rectify; FTcfg.Preproc.derivative = LoadedMat.FTcfg.Preproc.derivative; % Load GUI panel: if ~strcmp(FTcfg.GradCorrectCTF, 'none') set(handles.CheckboxGradCorrCTF, 'Value', 1); switch FTcfg.GradCorrectCTF.gradient case 'G1BR' GradCorrType = 'First-Order'; case 'G2BR' GradCorrType = 'Second-Order'; case 'G3BR' GradCorrType = 'Third-Order'; otherwise error('Unrecognized Option'); % error-check end DropdownOptions = get(handles.DropdownGradCorrCTF, 'String'); DropdownValue = find(strcmp(DropdownOptions, GradCorrType)); set(handles.DropdownGradCorrCTF, 'Value', DropdownValue); if DropdownValue == 0 error('Option does not exist in dropdown list.'); % error-check end else set(handles.CheckboxGradCorrCTF, 'Value', 0); set(handles.DropdownGradCorrCTF, 'Value', 3); end if strcmp(FTcfg.Preproc.hilbert, 'yes') set(handles.CheckboxHilbert, 'Value', 1); DropdownOptions = get(handles.DropdownHilbert, 'String') DropdownValue = find(strcmp(DropdownOptions, cfg.Preproc.hilbert)); set(handles.DropdownHilbert, 'Value', DropdownValue); else set(handles.CheckboxHilbert, 'Value', 0); end if strcmp(FTcfg.Preproc.rectify, 'yes') set(handles.CheckboxRectify, 'Value', 1); else set(handles.CheckboxRectify, 'Value', 0); end if strcmp(FTcfg.Preproc.derivative, 'yes') set(handles.CheckboxDerivative, 'Value', 1); else set(handles.CheckboxDerivative, 'Value', 0); end % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %--- Reset other adv. settings & GUI panel: ---% %----------------------------------------------% function OutputHandles = ResetOtherAdvSettings(InputHandles) handles = InputHandles; FTcfg = handles.FTcfg; % Reset FTcfg settings: FTcfg.GradCorrectCTF.gradient = 'G3BR'; FTcfg.GradCorrectCTF.trials = 'all'; FTcfg.Preproc.hilbert = 'no'; FTcfg.Preproc.rectify = 'no'; FTcfg.Preproc.derivative = 'no'; % Reset GUI panel: set(handles.CheckboxGradCorrCTF, 'Value', 1); set(handles.DropdownGradCorrCTF, 'Value', 1); set(handles.CheckboxHilbert, 'Value', 0); set(handles.DropdownHilbert, 'Value', 1); set(handles.CheckboxRectify, 'Value', 0); set(handles.CheckboxDerivative, 'Value', 0); % Set output handles: handles.FTcfg = FTcfg; OutputHandles = handles; %=====================================================% % FUNCTIONS TO SAVE, LOAD, AND LOCK PREPROC SETTINGS: % %=====================================================% %--- Executes on button press in ButtonSaveLockSettings. ---% %-----------------------------------------------------------% function ButtonSaveLockSettings_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end % Check textbox settings (Most have already been checked in previous sections): PrestimTime = str2num(get(handles.TextboxPrestimTime, 'String')); PoststimTime = str2num(get(handles.TextboxPoststimTime, 'String')); OverlapThreshold = str2num(get(handles.TextboxOverlapThreshold, 'String')); if isempty(PrestimTime) msgbox('Error: Pre-stimulus time must be specified.', 'Error:'); return; end if isempty(PoststimTime) msgbox('Error: Post-stimulus time must be specified.', 'Error:'); return; end if isempty(OverlapThreshold) msgbox('Error: Overlap threshold must be specified.', 'Error:') return; end IncStartTime = str2num(get(handles.TextboxIncEventStartTime, 'String')); IncEndTime = str2num(get(handles.TextboxIncEventEndTime, 'String')); if isempty(IncStartTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify start search time for included events.', 'Error:') return; end if isempty(IncEndTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify end search time for included events.', 'Error:') return; end ExcStartTime = str2num(get(handles.TextboxExcEventStartTime, 'String')); ExcEndTime = str2num(get(handles.TextboxExcEventEndTime, 'String')); if isempty(ExcStartTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify start search time for excluded events.', 'Error:') return; end if isempty(ExcEndTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify end search time for excluded events.', 'Error:') return; end if get(handles.CheckboxDemean, 'Value') == 1 BaselineStart = str2num(get(handles.TextboxBaselineStart, 'String')); BaselineEnd = str2num(get(handles.TextboxBaselineEnd, 'String')); if get(handles.CheckboxBaselineWholeTrial, 'Value') == 0 if isempty(BaselineStart) msgbox('Error: Baseline start time not specified.', 'Error:'); return; end if isempty(BaselineEnd) msgbox('Error: Baseline end time not specified.', 'Error:'); return; end end end % Warning & confirmation: prompt = {'WARNING:'; ''; 'Once settings are saved, they will be locked for current DataID.'; 'To modify settings afterwards, you will need to create new DataID'; 'or manually delete PreprocSettings .mat file.'; ''; 'Do you wish to continue?'}; ContinueSave = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(ContinueSave, 'NO') return; end FTcfg = handles.FTcfg; time = handles.time; CheckSavePath([handles.paths.DataID,'/PreprocSettings.mat'], 'PreprocMEG'); save([handles.paths.DataID,'/PreprocSettings.mat'], 'FTcfg', 'time'); % Feedback: if exist([handles.paths.DataID,'/PreprocSettings.mat'], 'file') msgbox('PreprocSettings.mat successfully saved.') else msgbox('Error: Failed to save PreprocSettings.mat') end % Lock GUI panels: handles.gui.LockPreprocSettings = 'on'; set(handles.ButtonSaveLockSettings, 'Enable', 'off'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'off'); handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonLoadPreprocSettings. ---% %--------------------------------------------------------------% function ButtonLoadPreprocSettings_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select root directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end % Select PreprocSettings .mat to load: [matfile, matpath] = uigetfile([handles.paths.Rootpath,... '/PreprocSettings.mat'], 'Load PreprocSettings from:', 'MultiSelect', 'off'); if matfile == 0 msgbox('PreprocSettings .mat was not selected.'); return; end % Start Waitbox: WaitBox = StartWaitBox('LOADING PREPROC SETTINGS:'); % Load PreprocSettings from .mat: % Note: No need to load data filetype here. LoadedMat = load([matpath,matfile]); handles = LoadEpochSettings (handles, LoadedMat); handles = LoadBaselineSettings (handles, LoadedMat); handles = LoadGeneralFilterSettings (handles, LoadedMat); handles = LoadBandstopFilterSettings (handles, LoadedMat); handles = LoadDFTFilterSettings (handles, LoadedMat); handles = LoadMedianFilterSettings (handles, LoadedMat); handles = LoadDetrendSettings (handles, LoadedMat); handles = LoadOtherAdvSettings (handles, LoadedMat); % Make sure settings unlocked: handles.gui.LockPreprocSettings = 'off'; set(handles.ButtonSaveLockSettings, 'Enable', 'on'); set(handles.ButtonLoadPreprocSettings, 'Enable', 'on'); % Update settings & GUI panels: handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %=================================% % FUNCTIONS TO RUN PREPROCESSING: % %=================================% %--- Executes on button press in ButtonEpochPreprocData. ---% %-----------------------------------------------------------% function ButtonEpochPreprocData_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) || isempty(handles.paths.DataID) msgbox('Warning: Create or load DataID first.', 'Warning:'); return; end if isempty(handles.name.CurrentGroupID) msgbox('Warning: Create or load a GroupID first.', 'Warning:'); return; end if isempty(handles.name.CurrentCondID) msgbox('Warning: Current CondID not selected yet.', 'Warning:'); return; end % Make sure Rootpath & DataID don't have spaces (will cause issues for AFNI later): CheckSpaces1 = strfind(handles.paths.Rootpath, ' '); CheckSpaces2 = strfind(handles.paths.DataID, ' '); if ~isempty(CheckSpaces1) || ~isempty(CheckSpaces2) message = {'Error: Target directory or DataID contains spaces.'; 'AFNI functions cannot read folder & file paths with spaces.'; 'AFNI functions are required for file conversions later on.'}; msgbox(message, 'Error:') return; end % Check unlocked textbox settings (Most have already been checked in previous sections): OverlapThreshold = str2num(get(handles.TextboxOverlapThreshold, 'String')); if isempty(OverlapThreshold) msgbox('Error: Overlap threshold must be specified.', 'Error:') return; end IncStartTime = str2num(get(handles.TextboxIncEventStartTime, 'String')); IncEndTime = str2num(get(handles.TextboxIncEventEndTime, 'String')); if isempty(IncStartTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify start search time for included events.', 'Error:') return; end if isempty(IncEndTime) && ~isempty(handles.epoch.IncludedEvents) msgbox('Error: Need to specify end search time for included events.', 'Error:') return; end ExcStartTime = str2num(get(handles.TextboxExcEventStartTime, 'String')); ExcEndTime = str2num(get(handles.TextboxExcEventEndTime, 'String')); if isempty(ExcStartTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify start search time for excluded events.', 'Error:') return; end if isempty(ExcEndTime) && ~isempty(handles.epoch.ExcludedEvents) msgbox('Error: Need to specify end search time for excluded events.', 'Error:') return; end % Update settings & GUI panels: handles = UpdateSubjIDSettings (handles); handles = UpdateInputDataSettings (handles); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); handles = UpdateEpochSettings (handles); handles = UpdateBaselineSettings (handles); handles = UpdateGeneralFilterSettings (handles); handles = UpdateBandstopFilterSettings (handles); handles = UpdateDFTFilterSettings (handles); handles = UpdateMedianFilterSettings (handles); handles = UpdateDetrendSettings (handles); handles = UpdateOtherAdvSettings (handles); % Check if PreprocSettings.mat exists: PreprocSettingsMat = [handles.paths.DataID,'/PreprocSettings.mat']; if ~exist(PreprocSettingsMat, 'file') message = {'Error: PreprocSettings.mat could not be found for DataID.'; 'To generate one, configure and save preprocessing settings in GUI.'}; msgbox(message, 'Error:'); return; end % Since certain time settings are NOT locked along with other settings, % need to update PreprocSettings.mat with current time settings. time = handles.time; save(PreprocSettingsMat, 'time', '-append'); % Save copy of PreprocInputMEG for current CondID: prompt = {'Save a copy of the CURRENT input settings?'; [' Group: ',handles.name.CurrentGroupID]; [' Cond: ',handles.name.CurrentCondID]}; SaveInput = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'YES'); if strcmp(SaveInput, 'YES') ButtonSaveInput_Callback(hObject, eventdata, handles); end % Check parallel computing: CheckOpenPCT % Run command to preprocess & epoch data: PreprocInputMEG.name.DataID = handles.name.DataID; PreprocInputMEG.name.SubjID = handles.name.SubjID; PreprocInputMEG.name.CurrentGroupID = handles.name.CurrentGroupID; PreprocInputMEG.name.CurrentCondID = handles.name.CurrentCondID; PreprocInputMEG.paths = handles.paths; PreprocInputMEG.epoch.TargetMarkers = handles.epoch.TargetMarkers; PreprocInputMEG.epoch.IncludedEvents = handles.epoch.IncludedEvents; PreprocInputMEG.epoch.ExcludedEvents = handles.epoch.ExcludedEvents; PreprocInputMEG.gui.DataFiletype = handles.gui.DataFiletype; disp('PREPROCESSING DATA:') MEGpipeline_PreprocMEG(PreprocSettingsMat, PreprocInputMEG); % Update Status: set(handles.CheckboxShowOutputStatus, 'Value', 1); handles = DetectStatus(handles); handles = UpdateStatusSettings (handles); % Clear CurrentCondID and AddedEvents for next CondID: % Note: No need to reset DetectedEvents or CondID folders. handles.name.CurrentCondID = []; handles.paths.CurrentCondID = []; handles.epoch.TargetMarkers = []; handles.epoch.IncludedEvents = []; handles.epoch.ExcludedEvents = []; set(handles.TextboxCurrentCondID, 'String', []); set(handles.ListboxTargetMarkers, 'String', []); set(handles.ListboxIncludedEvents, 'String', []); set(handles.ListboxExcludedEvents, 'String', []); handles = UpdateEventSettings (handles); handles = UpdateCondIDSettings (handles); % Save handles: guidata(hObject, handles); %=================================% % FUNCTION TO OPEN MODAL WAITBOX: % %=================================% function WaitBox = StartWaitBox(TextString) WaitBox = dialog('Units', 'pixels', 'Position', [500 500 300 40],... 'Windowstyle', 'modal', 'NextPlot', 'new', 'Name', 'Please Wait:'); uicontrol('Parent', WaitBox, 'Units', 'pixels', 'Position', [20 10 250 20],... 'Style', 'text', 'String', TextString, 'FontWeight', 'bold'); movegui(WaitBox, 'center'); %============================% % GUIDE CREATEFCN FUNCTIONS: % %============================% % --- Executes during object creation, after setting all properties. function TextboxRootpath_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxDataID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxGroupID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxSubjID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxSubjID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownDataFiletype_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxInputData_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxDetectedEvents_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxTargetMarkers_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxIncludedEvents_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxExcludedEvents_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxCondID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxCurrentCondID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxStatus_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxPrestimTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxPoststimTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxOverlapThreshold_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxIncEventStartTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxIncEventEndTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxExcEventStartTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxExcEventEndTime_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxPaddingLength_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxBaselineStart_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxBaselineEnd_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxHighpassFreq_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxLowpassFreq_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownPassFilterDir_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownPassFilterType_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxPassFilterOrder_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownPassFilterInstability_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxHighstopFreq_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxLowstopFreq_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownBandstopFilterDir_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownBandstopFilterType_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxBandstopFilterOrder_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownBandstopFilterInstability_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxDFTcustom_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxMedianFilterOrder_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxPolyremovalOrder_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownGradCorrCTF_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function DropdownHilbert_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end